中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何配置SpringMVC國際化

發布時間:2021-10-13 11:55:22 來源:億速云 閱讀:164 作者:iii 欄目:開發技術

本篇內容介紹了“如何配置SpringMVC國際化”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

如何配置SpringMVC國際化

1.SpringMVC 國際化配置

還是先來說說用法,再來說源碼,這樣大家不容易犯迷糊。我們先說在 SSM 中如何處理國際化問題。

首先國際化我們可能有兩種需求:

  • 在頁面渲染時實現國際化(這個借助于 Spring 標簽實現)

  • 在接口中獲取國際化匹配后的消息

大致上就是上面這兩種場景。接下來松哥通過一個簡單的用法來和大家演示下具體玩法。

首先我們在項目的 resources 目錄下新建語言文件,language_en_US.properties 和  language_zh-CN.properties,如下圖:

如何配置SpringMVC國際化

內容分別如下:

language_en_US.properties:

login.username=Username login.password=Password

language_zh-CN.properties:

login.username=用戶名 login.password=用戶密碼

這兩個分別對應英中文環境。配置文件寫好之后,還需要在 SpringMVC 容器中提供一個 ResourceBundleMessageSource  實例去加載這兩個實例,如下:

<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">     <property name="basename" value="language"/>     <property name="defaultEncoding" value="UTF-8"/> </bean>

這里配置了文件名 language 和默認的編碼格式。

接下來我們新建一個 login.jsp 文件,如下:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head>     <title>Title</title> </head> <body> <spring:message code="login.username"/> <input type="text"> <br> <spring:message code="login.password"/> <input type="text"> <br> </body> </html>

在這個文件中,我們通過 spring:message 標簽來引用變量,該標簽會根據當前的實際情況,選擇合適的語言文件。

接下來我們為 login.jsp 提供一個控制器:

@Controller public class LoginController {     @Autowired     MessageSource messageSource;     @GetMapping("/login")     public String login() {         String username = messageSource.getMessage("login.username", null, LocaleContextHolder.getLocale());         String password = messageSource.getMessage("login.password", null, LocaleContextHolder.getLocale());         System.out.println("username = " + username);         System.out.println("password = " + password);         return "login";     } }

控制器中直接返回 login 視圖即可。

另外我這還注入了 MessageSource 對象,主要是為了向大家展示如何在處理器中獲取國際化后的語言文字。

配置完成后,啟動項目進行測試。

默認情況下,系統是根據請求頭的中 Accept-Language 字段來判斷當前的語言環境的,該這個字段由瀏覽器自動發送,我們這里為了測試方便,可以使用  POSTMAN 進行測試,然后手動設置 Accept_Language 字段。

首先測試中文環境:

如何配置SpringMVC國際化

然后測試英文環境:

如何配置SpringMVC國際化

都沒問題,完美!同時觀察 IDEA 控制臺,也能正確打印出語言文字。

上面這個是基于 AcceptHeaderLocaleResolver 來解析出當前的區域和語言的。

有的時候,我們希望語言環境直接通過請求參數來傳遞,而不是通過請求頭來傳遞,這個需求我們通過 SessionLocaleResolver 或者  CookieLocaleResolver 都可以實現。

先來看 SessionLocaleResolver。

首先在 SpringMVC 配置文件中提供 SessionLocaleResolver 的實例,同時配置一個攔截器,如下:

<mvc:interceptors>     <mvc:interceptor>         <mvc:mapping path="/**"/>         <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">             <property name="paramName" value="locale"/>         </bean>     </mvc:interceptor> </mvc:interceptors> <bean class="org.springframework.web.servlet.i18n.SessionLocaleResolver" id="localeResolver"> </bean>

SessionLocaleResolver 是負責區域解析的,這個沒啥好說的。攔截器 LocaleChangeInterceptor  則主要是負責參數解析的,我們在配置攔截器的時候,設置了參數名為 locale(默認即此),也就是說我們將來可以通過 locale  參數來傳遞當前的環境信息。

配置完成后,我們還是來訪問剛才的 login 控制器,如下:

如何配置SpringMVC國際化

此時我們可以直接通過 locale 參數來控制當前的語言環境,這個 locale 參數就是在前面所配置的 LocaleChangeInterceptor  攔截器中被自動解析的。

如果你不想配置 LocaleChangeInterceptor 攔截器也是可以的,直接自己手動解析 locale 參數然后設置 locale  也行,像下面這樣:

@Controller public class LoginController {     @Autowired     MessageSource messageSource;     @GetMapping("/login")     public String login(String locale,HttpSession session) {         if ("zh-CN".equals(locale)) {             session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale("zh", "CN"));         } else if ("en-US".equals(locale)) {             session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale("en", "US"));         }         String username = messageSource.getMessage("login.username", null, LocaleContextHolder.getLocale());         String password = messageSource.getMessage("login.password", null, LocaleContextHolder.getLocale());         System.out.println("username = " + username);         System.out.println("password = " + password);         return "login";     } }

SessionLocaleResolver 所實現的功能也可以通過 CookieLocaleResolver  來實現,不同的是前者將解析出來的區域信息保存在 session 中,而后者則保存在 Cookie 中。保存在 session 中,只要 session  沒有發生變化,后續就不用再次傳遞區域語言參數了,保存在 Cookie 中,只要 Cookie 沒變,后續也不用再次傳遞區域語言參數了。

使用 CookieLocaleResolver 的方式很簡單,直接在 SpringMVC 中提供 CookieLocaleResolver  的實例即可,如下:

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

注意這里也需要使用到 LocaleChangeInterceptor  攔截器,如果不使用該攔截器,則需要自己手動解析并配置語言環境,手動解析并配置的方式如下:

@GetMapping("/login3") public String login3(String locale, HttpServletRequest req, HttpServletResponse resp) {     CookieLocaleResolver resolver = new CookieLocaleResolver();     if ("zh-CN".equals(locale)) {         resolver.setLocale(req, resp, new Locale("zh", "CN"));     } else if ("en-US".equals(locale)) {         resolver.setLocale(req, resp, new Locale("en", "US"));     }     String username = messageSource.getMessage("login.username", null, LocaleContextHolder.getLocale());     String password = messageSource.getMessage("login.password", null, LocaleContextHolder.getLocale());     System.out.println("username = " + username);     System.out.println("password = " + password);     return "login"; }

配置完成后,啟動項目進行測試,這次測試的方式跟 SessionLocaleResolver 的測試方式一致,松哥就不再多說了。

除了前面介紹的這幾種 LocaleResolver 之外,還有一個  FixedLocaleResolver,因為比較少見,松哥這里就不做過多介紹了。

2.Spring Boot 國際化配置

2.1 基本使用

Spring Boot 和 Spring 一脈相承,對于國際化的支持,默認是通過 AcceptHeaderLocaleResolver  解析器來完成的,這個解析器,默認是通過請求頭的 Accept-Language 字段來判斷當前請求所屬的環境的,進而給出合適的響應。

所以在 Spring Boot 中做國際化,這一塊我們可以不用配置,直接就開搞。

首先創建一個普通的 Spring Boot 項目,添加 web 依賴即可。項目創建成功后,默認的國際化配置文件放在 resources  目錄下,所以我們直接在該目錄下創建四個測試文件,如下:

如何配置SpringMVC國際化

  • 我們的 message 文件是直接創建在 resources 目錄下的,IDEA 在展示的時候,會多出一個 Resource  Bundle,這個大家不用管,千萬別手動去創建這個目錄。

  • messages.properties 這個是默認的配置,其他的則是不同語言環境下的配置,en_US 是英語(美國),zh_CN 是中文簡體,zh_TW  是中文繁體(文末附錄里邊有一個完整的語言簡稱表格)。

四個文件創建好之后,第一個默認的我們可以先空著,另外三個分別填入以下內容:

messages_zh_CN.properties

user.name=江南一點雨

messages_zh_TW.properties

user.name=江南壹點雨

messages_en_US.properties

user.name=javaboy

配置完成后,我們就可以直接開始使用了。在需要使用值的地方,直接注入 MessageSource 實例即可。

在 Spring 中需要配置的 MessageSource 現在不用配置了,Spring Boot 會通過  org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration  自動幫我們配置一個 MessageSource 實例。

創建一個 HelloController ,內容如下:

@RestController public class HelloController {     @Autowired     MessageSource messageSource;     @GetMapping("/hello")     public String hello() {         return messageSource.getMessage("user.name", null, LocaleContextHolder.getLocale());     } }

在 HelloController 中我們可以直接注入 MessageSource 實例,然后調用該實例中的 getMessage  方法去獲取變量的值,第一個參數是要獲取變量的 key,第二個參數是如果 value 中有占位符,可以從這里傳遞參數進去,第三個參數傳遞一個 Locale  實例即可,這相當于當前的語言環境。

接下來我們就可以直接去調用這個接口了。

默認情況下,在接口調用時,通過請求頭的 Accept-Language 來配置當前的環境,我這里通過 POSTMAN 來進行測試,結果如下:

如何配置SpringMVC國際化

小伙伴們看到,我在請求頭中設置了 Accept-Language 為 zh-CN,所以拿到的就是簡體中文;如果我設置了  zh-TW,就會拿到繁體中文:

如何配置SpringMVC國際化

是不是很 Easy?

2.2 自定義切換

有的小伙伴覺得切換參數放在請求頭里邊好像不太方便,那么也可以自定義解析方式。例如參數可以當成普通參數放在地址欄上,通過如下配置可以實現我們的需求。

@Configuration public class WebConfig implements WebMvcConfigurer {     @Override     public void addInterceptors(InterceptorRegistry registry) {         LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();         interceptor.setParamName("lang");         registry.addInterceptor(interceptor);     }     @Bean     LocaleResolver localeResolver() {         SessionLocaleResolver localeResolver = new SessionLocaleResolver();         localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);         return localeResolver;     } }

在這段配置中,我們首先提供了一個 SessionLocaleResolver 實例,這個實例會替換掉默認的  AcceptHeaderLocaleResolver,不同于 AcceptHeaderLocaleResolver  通過請求頭來判斷當前的環境信息,SessionLocaleResolver 將客戶端的 Locale 保存到 HttpSession  對象中,并且可以進行修改(這意味著當前環境信息,前端給瀏覽器發送一次即可記住,只要 session 有效,瀏覽器就不必再次告訴服務端當前的環境信息)。

另外我們還配置了一個攔截器,這個攔截器會攔截請求中 key 為 lang 的參數(不配置的話是 locale),這個參數則指定了當前的環境信息。

好了,配置完成后,啟動項目,訪問方式如下:

如何配置SpringMVC國際化

我們通過在請求中添加 lang 來指定當前環境信息。這個指定只需要一次即可,也就是說,在 session 不變的情況下,下次請求可以不必帶上 lang  參數,服務端已經知道當前的環境信息了。

CookieLocaleResolver 也是類似用法,不再贅述。

2.3 其他自定義

默認情況下,我們的配置文件放在 resources 目錄下,如果大家想自定義,也是可以的,例如定義在 resources/i18n 目錄下:

如何配置SpringMVC國際化

但是這種定義方式系統就不知道去哪里加載配置文件了,此時還需要 application.properties  中進行額外配置(注意這是一個相對路徑):

spring.messages.basename=i18n/messages

另外還有一些編碼格式的配置等,內容如下:

spring.messages.cache-duration=3600 spring.messages.encoding=UTF-8 spring.messages.fallback-to-system-locale=true

spring.messages.cache-duration 表示 messages 文件的緩存失效時間,如果不配置則緩存一直有效。

spring.messages.fallback-to-system-locale  屬性則略顯神奇,網上竟然看不到一個明確的答案,后來翻了一會源碼才看出端倪。

這個屬性的作用在  org.springframework.context.support.AbstractResourceBasedMessageSource#getDefaultLocale  方法中生效:

protected Locale getDefaultLocale() {  if (this.defaultLocale != null) {   return this.defaultLocale;  }  if (this.fallbackToSystemLocale) {   return Locale.getDefault();  }  return null; }

從這段代碼可以看出,在找不到當前系統對應的資源文件時,如果該屬性為 true,則會默認查找當前系統對應的資源文件,否則就返回 null,返回 null  之后,最終又會調用到系統默認的 messages.properties 文件。

3.LocaleResolver

國際化這塊主要涉及到的組件是 LocaleResolver,這是一個開放的接口,官方默認提供了四個實現。當前該使用什么環境,主要是通過  LocaleResolver 來進行解析的。

LocaleResolver

public interface LocaleResolver {  Locale resolveLocale(HttpServletRequest request);  void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale);  }

這里兩個方法:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. resolveLocale:根據當前請求解析器出 Locale 對象。

  3. 設置 Locale 對象。

我們來看看 LocaleResolver 的繼承關系:

如何配置SpringMVC國際化

雖然中間有幾個抽象類,不過最終負責實現的其實就四個:

  • AcceptHeaderLocaleResolver:根據請求頭中的 Accept-Language 字段來確定當前的區域語言等。

  • SessionLocaleResolver:根據請求參數來確定區域語言等,確定后會保存在 Session 中,只要 Session 不變,Locale  對象就一直有效。

  • CookieLocaleResolver:根據請求參數來確定區域語言等,確定后會保存在 Cookie 中,只要 Session 不變,Locale  對象就一直有效。

  • FixedLocaleResolver:配置時直接提供一個 Locale 對象,以后不能修改。

接下來我們就對這幾個類逐一進行分析。

3.1 AcceptHeaderLocaleResolver

AcceptHeaderLocaleResolver 直接實現了 LocaleResolver 接口,我們來看它的 resolveLocale  方法:

@Override public Locale resolveLocale(HttpServletRequest request) {  Locale defaultLocale = getDefaultLocale();  if (defaultLocale != null && request.getHeader("Accept-Language") == null) {   return defaultLocale;  }  Locale requestLocale = request.getLocale();  List<Locale> supportedLocales = getSupportedLocales();  if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) {   return requestLocale;  }  Locale supportedLocale = findSupportedLocale(request, supportedLocales);  if (supportedLocale != null) {   return supportedLocale;  }  return (defaultLocale != null ? defaultLocale : requestLocale); }
  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 首先去獲取默認的 Locale 對象。

  3. 如果存在默認的 Locale 對象,并且請求頭中沒有設置 Accept-Language 字段,則直接返回默認的 Locale。

  4. 從 request 中取出當前的 Locale 對象,然后查詢出支持的 supportedLocales,如果 supportedLocales 或者  supportedLocales 中包含 requestLocale,則直接返回 requestLocale。

  5. 如果前面還是沒有匹配成功的,則從 request 中取出 locales 集合,然后再去和支持的 locale 進行比對,選擇匹配成功的 locale  返回。

  6. 如果前面都沒能返回,則判斷 defaultLocale 是否為空,如果不為空,就返回 defaultLocale,否則返回  defaultLocale。

再來看看它的 setLocale 方法,直接拋出異常,意味著通過請求頭處理 Locale 是不允許修改的。

@Override public void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) {  throw new UnsupportedOperationException(    "Cannot change HTTP accept header - use a different locale resolution strategy"); }

3.2 SessionLocaleResolver

SessionLocaleResolver 的實現多了一個抽象類  AbstractLocaleContextResolver,AbstractLocaleContextResolver 中增加了對 TimeZone  的支持,我們先來看下 AbstractLocaleContextResolver:

public abstract class AbstractLocaleContextResolver extends AbstractLocaleResolver implements LocaleContextResolver {  @Nullable  private TimeZone defaultTimeZone;  public void setDefaultTimeZone(@Nullable TimeZone defaultTimeZone) {   this.defaultTimeZone = defaultTimeZone;  }  @Nullable  public TimeZone getDefaultTimeZone() {   return this.defaultTimeZone;  }  @Override  public Locale resolveLocale(HttpServletRequest request) {   Locale locale = resolveLocaleContext(request).getLocale();   return (locale != null ? locale : request.getLocale());  }  @Override  public void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) {   setLocaleContext(request, response, (locale != null ? new SimpleLocaleContext(locale) : null));  }  }

可以看到,多了一個 TimeZone 屬性。從請求中解析出 Locale 還是調用了 resolveLocaleContext  方法,該方法在子類中被實現,另外調用 setLocaleContext 方法設置 Locale,該方法的實現也在子類中。

我們來看下它的子類 SessionLocaleResolver:

@Override public Locale resolveLocale(HttpServletRequest request) {  Locale locale = (Locale) WebUtils.getSessionAttribute(request, this.localeAttributeName);  if (locale == null) {   locale = determineDefaultLocale(request);  }  return locale; }

直接從 Session 中獲取 Locale,默認的屬性名是 SessionLocaleResolver.class.getName() +  ".LOCALE",如果 session 中不存在 Locale 信息,則調用 determineDefaultLocale 方法去加載  Locale,該方法會首先找到 defaultLocale,如果 defaultLocale 不為 null 就直接返回,否則就從 request 中獲取  Locale 返回。

再來看 setLocaleContext 方法,就是將解析出來的 Locale 保存起來。

@Override public void setLocaleContext(HttpServletRequest request, @Nullable HttpServletResponse response,   @Nullable LocaleContext localeContext) {  Locale locale = null;  TimeZone timeZone = null;  if (localeContext != null) {   locale = localeContext.getLocale();   if (localeContext instanceof TimeZoneAwareLocaleContext) {    timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();   }  }  WebUtils.setSessionAttribute(request, this.localeAttributeName, locale);  WebUtils.setSessionAttribute(request, this.timeZoneAttributeName, timeZone); }

保存到 Session 中即可。大家可以看到,這種保存方式其實和我們前面演示的自己保存代碼基本一致,殊途同歸。

3.3 FixedLocaleResolver

FixedLocaleResolver 有三個構造方法,無論調用哪一個,都會配置默認的 Locale:

public FixedLocaleResolver() {  setDefaultLocale(Locale.getDefault()); } public FixedLocaleResolver(Locale locale) {  setDefaultLocale(locale); } public FixedLocaleResolver(Locale locale, TimeZone timeZone) {  setDefaultLocale(locale);  setDefaultTimeZone(timeZone); }

要么自己傳 Locale 進來,要么調用 Locale.getDefault() 方法獲取默認的 Locale。

再來看 resolveLocale 方法:

@Override public Locale resolveLocale(HttpServletRequest request) {  Locale locale = getDefaultLocale();  if (locale == null) {   locale = Locale.getDefault();  }  return locale; }

這個應該就不用解釋了吧。

需要注意的是它的 setLocaleContext 方法,直接拋異常出來,也就意味著 Locale 在后期不能被修改。

@Override public void setLocaleContext( HttpServletRequest request, @Nullable HttpServletResponse response,   @Nullable LocaleContext localeContext) {  throw new UnsupportedOperationException("Cannot change fixed locale - use a different locale resolution strategy"); }

3.4 CookieLocaleResolver

CookieLocaleResolver 和 SessionLocaleResolver 比較類似,只不過存儲介質變成了  Cookie,其他都差不多,松哥就不再重復介紹了。

4.附錄

搜刮了一個語言簡稱表,分享給各位小伙伴:

語言簡稱
簡體中文(中國)zh_CN
繁體中文(中國臺灣)zh_TW
繁體中文(中國香港)zh_HK
英語(中國香港)en_HK
英語(美國)en_US
英語(英國)en_GB
英語(全球)en_WW
英語(加拿大)en_CA
英語(澳大利亞)en_AU
英語(愛爾蘭)en_IE
英語(芬蘭)en_FI
芬蘭語(芬蘭)fi_FI
英語(丹麥)en_DK
丹麥語(丹麥)da_DK
英語(以色列)en_IL
希伯來語(以色列)he_IL
英語(南非)en_ZA
英語(印度)en_IN
英語(挪威)en_NO
英語(新加坡)en_SG
英語(新西蘭)en_NZ
英語(印度尼西亞)en_ID
英語(菲律賓)en_PH
英語(泰國)en_TH
英語(馬來西亞)en_MY
英語(阿拉伯)en_XA
韓文(韓國)ko_KR
日語(日本)ja_JP
荷蘭語(荷蘭)nl_NL
荷蘭語(比利時)nl_BE
葡萄牙語(葡萄牙)pt_PT
葡萄牙語(巴西)pt_BR
法語(法國)fr_FR
法語(盧森堡)fr_LU
法語(瑞士)fr_CH
法語(比利時)fr_BE
法語(加拿大)fr_CA
西班牙語(拉丁美洲)es_LA
西班牙語(西班牙)es_ES
西班牙語(阿根廷)es_AR
西班牙語(美國)es_US
西班牙語(墨西哥)es_MX
西班牙語(哥倫比亞)es_CO
西班牙語(波多黎各)es_PR
德語(德國)de_DE
德語(奧地利)de_AT
德語(瑞士)de_CH
俄語(俄羅斯)ru_RU
意大利語(意大利)it_IT
希臘語(希臘)el_GR
挪威語(挪威)no_NO
匈牙利語(匈牙利)hu_HU
土耳其語(土耳其)tr_TR
捷克語(捷克共和國)cs_CZ
斯洛文尼亞語sl_SL
波蘭語(波蘭)pl_PL
瑞典語(瑞典)sv_SE
西班牙語(智利)es_CL

“如何配置SpringMVC國際化”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

界首市| 耒阳市| 临沭县| 晋州市| 永定县| 淮滨县| 巴南区| 万源市| 泰安市| 尉氏县| 河曲县| 平谷区| 平乐县| 义乌市| 曲靖市| 辽宁省| 剑河县| 桑植县| 清苑县| 蓬溪县| 新平| 扶沟县| 于田县| 安阳县| 嘉黎县| 津南区| 乳山市| 郧西县| 石渠县| 通渭县| 和田县| 琼中| 耿马| 买车| 西和县| 三江| 江川县| 噶尔县| 安乡县| 昔阳县| 天水市|