日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring MVC-08循序渐进之国际化(AcceptHeaderLocaleResolver)

發布時間:2025/3/21 javascript 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC-08循序渐进之国际化(AcceptHeaderLocaleResolver) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  • 概述
  • 概述
  • 國際化SpringMVC應用程序
    • 將文本元件隔離成屬性文件
    • 選擇和讀取正確的屬性文件
  • 告訴Spring MVC使用哪個語言區域
  • 使用message標簽
  • Demo
  • 測試
  • 源碼

概述

我們之前梳理過Spring相關的國際化的知識點,如下

Spring-國際化信息01-基礎知識

Spring-國際化信息02-MessageSource接口

Spring-國際化信息03-容器級的國際化信息資源

在這里,我們將國際化與Spring MVC結合起來,看SpringMVC如何整合國際化(其實03中已經闡述了)。

這里我們來重新看下


概述

概括的來講,我們需要了解兩個術語

  • 國際化,即我們常講的i18n (internationalization 以i開頭n結尾,中間有18個字母)

  • 本地化,即我們常講的L10N(localization,中間的 10 代表在首字母“L”和尾字母“N”之間省略了 10 個字母) 。這是將國際化應用程序改成支持特定語言區域(locale)的技術。 舉個例子:同樣是日期,2018年02月27日 , 美國顯示為02/27/2018, 澳大利亞則為27/02/2018 , 中國就是2018/02/27。

Java為字符和字符串提供了unicode支持,因此使用Java編寫國際化的應用程序是一件很容易的事情。

國際化應用程序的具體方式取決于有多少靜態數據需要以不同的語言顯示出來,一般來講

  • 如果大量數據都是靜態的,就要針對每一個語言區域單獨創建一個資源版本,這種一般適用于帶有大量靜態HTML頁面的Web應用程序。這個很簡單,我們不討論這個.

  • 如果需要國際化的靜態數據量有限,就可以將文本元素,比如元件標簽和錯誤消息隔離成文本文件。每個文本文件中都保存著一個語言區域的所有文本元素譯文。 隨后,應用程序會自動獲取每一個元素,這樣做的優勢是顯而易見的。我們這里討論是這種場景。


國際化SpringMVC應用程序

國際化和本地化應用程序時,需要具備以下條件:

1. 將文本元文件隔離成屬性文件

2. 選擇和讀取正確的屬性文件


將文本元件隔離成屬性文件

被國際化的應用程序是將每一個語言區域的文本元素都單獨保存在一個獨立的屬性文件中。 每個文件中都包含key/value對,并且每個key都是唯一標示一個特定語言區域的對象 。

key始終是字符串,value則可以是字符串,也可以是其他任意類型的對象。

為了支持美國英語、漢語,就要有2個屬性文件,他們都有著相同的key.

比如英語版本

greetings=hello farewell=goodbye

漢語版本

greetings=\u4F60\u597D farewell=\u518D\u89C1

漢語中的屬性文件value,漢字需要轉換為Unicode碼, 一般IDE都會自帶這種轉換功能。我們直接輸入漢字,就可以直接得到對應的Unicode碼了。

接下來我們要學習java.util.ResourceBundle ,
詳見 http://blog.csdn.net/yangshangwei/article/details/76946002#t8

ResourceBundle能夠輕松的選擇和讀取特定用戶語言區域的屬性,以及查找值。 ResourceBundle是一個抽象類,但它提供了靜態的getBundle方法,以返回一個具體子類的實例。

ResourceBundle有一個基準名,它可以是任意名稱。 但為了讓ResourceBundle正確的選擇屬性文件,這個文件名中最好必須包含基準名ResourceBundle,后面再接下劃線、語言碼,還可以選擇再加一條下劃線和國家碼。

basename_languageCode_countryCode

假設基準名為MyResource, 并且定義了2個語言區域

  • US-en
  • CN-zh

那么,就會得到如下2個屬性文件

  • MyResource_en_US.properties
  • MyResource_zh_CN.properties

選擇和讀取正確的屬性文件

如前所述,雖然ResourceBundle是一個抽象類,但是它提供了靜態的getBundle方法來獲取一個ResourceBundle實例

比如

如果沒有找到合適的屬性文件,ResourceBundle對象就會返回到默認的屬性文件, 默認的屬性文件為基準名加上一個擴展名properties. 如果默認文件也沒有找到,則將拋出java.util.MissingResourceException.

隨后讀取值,利用getString方法即可,如果未找到指定的key,則將拋出java.util.MissingResourceException.

但在SpringMVC中,我們不直接使用ResourceBundle,而是利用messageSource bean來告訴Spring MVC要將屬性文件保存在哪里

<bean id="messageSource"class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><property name="basenames" ><list><value>/WEB-INF/resource/messages</value><value>/WEB-INF/resource/labels</value></list></property></bean>

上面的bean定義中用ReloadableResourceBundleMessageSource類作為實現, 另外一個是ResourceBundleMessageSource,但是ResourceBundleMessageSource不能重新加載,這意味著如果有任何屬性文件中修改了某一個屬性key或者value,并且正在使用ResourceBundleMessageSource,那么要使生效的話,就必須要重啟JVM。

<bean id="resource"class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><property name="basenames" ref="resourceList"/><!-- 刷新資源文件的周期,以秒為單位 --><property name="cacheSeconds" value="5"/></bean><util:list id="resourceList"><value>i18n/fmt_resource</value></util:list>

這兩個實現之間的另外一區別是: ReloadableResourceBundleMessageSource是在應用程序目錄下搜索這些屬性文件,而使用ResourceBundleMessageSource,屬性文件則必須放在類路徑下,即WEB-INF/class目錄下。

如果只有一組屬性文件,則可以使用basename屬性代替basenames

<bean id="messageSource"class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><property name="basename" ><list><value>/WEB-INF/resource/messages</value></list></property></bean>

告訴Spring MVC使用哪個語言區域

為用戶選擇語言區域時,最常用的方法或許是通過讀取用戶瀏覽器的accept-language標題值。 accept-language標題提供了用戶偏好哪種語言的信息.

選擇語言區域的其他方法還包括讀取某個session屬性或者cookie。

在Spring MVC中選擇語言區域,可以使用語言解析器Bean,它包括幾個實現,如下

  • AcceptHeaderLocaleResolver
  • SessionLocaleResolver
  • CookieLocaleResolver

這些實現都是org.springframework.web.servlet.i18n包的組成部分。 AcceptHeaderLocaleResolver或許是最容易使用的一個。

如果使用AcceptHeaderLocaleResolver這個語言區域解析器,Spring MVC將會讀取瀏覽器的accept-language標題,來確定瀏覽器接受哪個語言區域. 如果與應用程序支持的語言匹配,這就會使用這個語言區域,否則就會使用默認的語言區域。

下面是使用AcceptHeaderLocaleResolver的localeResolver bean定義

<bean id="localeResolver"class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"></bean>

使用message標簽

在Spring MVC中顯示本地化消息的最容易方法就是使用Spring的message標簽。

為了使用message標簽,需要在使用該標簽的所有JSP頁面最前面聲明這個taglib指令

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

message標簽屬性如下,均是可選項

屬性描述
arguments該標簽的參數寫成一個有界的字符、一個對象數組或者單個對象
argumentSeparator用來分隔該標簽參數的字符
code獲取消息的key
htmlEscape接受True或者False,表示被渲染文本是否應該進行HTML轉義
JavaScriptEscape接受True或者False,表示被渲染文本是否應該進行JavaScript轉義
messageMessageSourceResolvable參數
scope保存var屬性中定義的變量的范圍
text如果code屬性不存在,或者指定碼無法獲取消息時,所顯示的默認文本
var用來保存消息的有界變量

Demo

Domain類

package com.artisan.domain; import java.io.Serializable;import javax.validation.constraints.Size;import org.hibernate.validator.constraints.NotBlank;public class Product implements Serializable {private static final long serialVersionUID = 78L;@NotBlank@Size(min=1, max=10)private String name;private String description;private Float price;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public Float getPrice() {return price;}public void setPrice(Float price) {this.price = price;} }

控制層

package com.artisan.controller;import javax.validation.Valid;import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping;import com.artisan.domain.Product;@Controller @RequestMapping("/product") public class ProductController {private static final Log logger = LogFactory.getLog(ProductController.class);@RequestMapping(value="/product_input")public String inputProduct(Model model) {model.addAttribute("product", new Product());return "ProductForm";}@RequestMapping(value="/product_save")public String saveProduct(@Valid @ModelAttribute Product product, BindingResult bindingResult,Model model) {// 校驗if (bindingResult.hasErrors()) {FieldError fieldError = bindingResult.getFieldError();logger.info("Code:" + fieldError.getCode() + " ,field:" + fieldError.getField());return "ProductForm";}// save product heremodel.addAttribute("product", product);return "ProductDetails";}}

Spring MVC配置文件

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 掃描控制層的注解,使其成為Spring管理的Bean --><context:component-scan base-package="com.artisan.controller" /><!-- 靜態資源文件 --><mvc:annotation-driven /><mvc:resources mapping="/css/**" location="/css/" /><mvc:resources mapping="/*.jsp" location="/" /><!-- 視圖解析器 --><bean id="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/" /><property name="suffix" value=".jsp" /></bean><!-- 國際化資源文件 --><bean id="messageSource"class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><property name="basenames"><list><value>/WEB-INF/resource/messages</value><value>/WEB-INF/resource/labels</value></list></property><!-- 如果在國際化資源文件中找不到對應代碼的信息,就用這個代碼作為名稱 --><property name="useCodeAsDefaultMessage" value="true" /></bean><bean id="localeResolver"class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"></bean></beans>

這里用到了messageSource 和 localeResolver 這兩個bean。 messageSource 聲明用兩個基準名設置了basenames屬性 /WEB-INF/resource/messages 和 /WEB-INF/resource/labels 。 localeResolver 利用 AcceptHeaderLocaleResolver類實現消息的本地化。

我們支持en和zh兩種語言區域,因此屬性文件都有兩個版本,除此之外我們還添加了當兩種都找不到時的默認語言區域的版本。

為了實現本地化,JSP頁面中的每一段文本都要用message標簽代替。
為了方便查看,我們將當前語言區域和accept-language標題顯示在頁面的最上方

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML> <html> <head> <title><spring:message code="page.productform.title"/></title> <style type="text/css">@import url("<c:url value="/css/main.css"/>");</style> </head> <body><div id="global"><!-- 為方便查看,這里打印出來當前的語言和accept-language --><!-- 為防止編譯報錯,pom中需要加入jsp-api依賴-->Current Locale : ${pageContext.response.locale}<br/>accept-language header: ${header["accept-language"]}<br/> <form:form commandName="product" action="product_save" method="post"><fieldset><legend><spring:message code="form.name"/></legend><p><label for="name"><spring:message code="label.productName" text="default text" />:</label><form:input id="name" path="name" cssErrorClass="error"/><form:errors path="name" cssClass="error"/></p><p><label for="description"><spring:message code="label.description"/>: </label><form:input id="description" path="description"/></p><p><label for="price"><spring:message code="label.price" text="default text" />: </label><form:input id="price" path="price" cssErrorClass="error"/></p><p id="buttons"><input id="reset" type="reset" tabindex="4" value="<spring:message code="button.reset"/>"><input id="submit" type="submit" tabindex="5" value="<spring:message code="button.submit"/>"></p></fieldset></form:form> </div> </body> </html>

測試

Accept-Language說明 :https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Language

指令

<language> 用含有兩到三個字符的字符串表示的語言碼。 <locale> 完整的語言標簽。除了語言本身之外,還會包含其他方面的信息,顯示在中劃線("-")后面。最常見的額外信息是國家或地區變種(如"en-US")或者表示所用的字母系統(如"sr-Lat")。其他變種諸如拼字法("de-DE-1996")等通常不被應用在這種場合。 * 任意語言;"*"表示通配符。 ;q= (q-factor weighting) 值代表優先順序,用相對質量價值 表示,又稱為權重。


源碼

代碼已提交到github

https://github.com/yangshangwei/SpringMvcTutorialArtisan

總結

以上是生活随笔為你收集整理的Spring MVC-08循序渐进之国际化(AcceptHeaderLocaleResolver)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。