文章目錄
使用SpringMVC來做國際化只有三步:
①寫好國際化文件。
②讓SpringMVC的ResourceBundleMessageSource管理國際化資源文件。
③直接去頁面取值。
一、SpringMVC國際化的步驟
1.國際化文件
僅以中英國際化爲例,國際化文件的文件名如下:
- i18n_zh_CN.properties 中文(簡體)
- i18n_en_US.properties 英語(美國)
- i18n_en.properties 中文
- i18n_zh.properties 英文
創建哪種文件可以根據上圖中瀏覽器的的語言環境。
2.SpringMVC管理國際化資源文件
- 在SpringMVC中配置
ResourceBundleMessageSource
。 - value=“loginpage/i18n”:表示配置文件爲loginpage文件夾下的i18n。
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="loginpage/i18n"></property>
</bean>
3.在頁面取值
- 在顯示頁面使用
fmt
進行取值。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>
<fmt:message key="welcomeinfo"/>
</h1>
<form action="">
<fmt:message key="username"/>:<input/><br/>
<fmt:message key="password"/>:<input/><br/>
<input type="submit" value="<fmt:message key="loginBtn"/>">
</form>
</body>
</html>
二、國際化區域信息解析器
private LocaleResolver localeResolver;
:SpringMVC中的區域信息是由這個區域信息解析器得到的,該解析器是SpringMVC九大組件之一。
所有用到區域信息的地方,都是用LocaleResolver默認裝配的AcceptHeaderLocaleResolver
來獲取 。
(1) AcceptHeaderLocaleResolver:使用請求頭的區域信息
源碼:
public class AcceptHeaderLocaleResolver implements LocaleResolver {
...
@Override
public Locale resolveLocale(HttpServletRequest request) {
return request.getLocale();
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
throw new UnsupportedOperationException(
"Cannot change HTTP accept header - use a different locale resolution strategy");
}
...
}
(2) FixedLocaleResolver:使用系統默認的區域信息
源碼:
public class FixedLocaleResolver extends AbstractLocaleContextResolver {
...
@Override
public Locale resolveLocale(HttpServletRequest request) {
Locale locale = getDefaultLocale();
if (locale == null) {
locale = Locale.getDefault();
}
return locale;
}
@Override
public LocaleContext resolveLocaleContext(HttpServletRequest request) {
return new TimeZoneAwareLocaleContext() {
@Override
public Locale getLocale() {
return getDefaultLocale();
}
@Override
public TimeZone getTimeZone() {
return getDefaultTimeZone();
}
};
}
@Override
public void setLocaleContext(HttpServletRequest request, HttpServletResponse response, LocaleContext localeContext) {
throw new UnsupportedOperationException("Cannot change fixed locale - use a different locale resolution strategy");
}
...
}
(3) SessionLocaleResolver:區域信息是從Session中獲取
源碼:
public class SessionLocaleResolver extends AbstractLocaleContextResolver {
...
@Override
public Locale resolveLocale(HttpServletRequest request) {
Locale locale = (Locale) WebUtils.getSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME);
if (locale == null) {
locale = determineDefaultLocale(request);
}
return locale;
}
...
}
(4)CookieLocaleResolver:區域信息是從Cookie中獲取
public class CookieLocaleResolver extends CookieGenerator implements LocaleContextResolver {
...
@Override
public Locale resolveLocale(HttpServletRequest request) {
parseLocaleCookieIfNecessary(request);
return (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);
}
...
}
三、在程序中獲取國際化信息
- 這樣有什麼用呢?之前在做JSR303校驗時,如果不使用表單標籤,而使用原生表單,可以增加Model參數,可以把國際化信息拿到後放入隱含模型中,再到頁面中取出。
@Autowired
private ResourceBundleMessageSource messageSource;
@RequestMapping("/tologinPage")
public String tologinpage(Locale locale) {
System.out.println(locale);
String message = messageSource.getMessage("welcomeinfo", null, locale);
System.out.println(message);
return "login";
}
四、擴展:點擊鏈接切換國際化
方式1:自定義區域信息解析器
處理器頁面
@Autowired
private ResourceBundleMessageSource messageSource;
@RequestMapping("/tologinPage")
public String tologinpage(Locale locale) {
System.out.println(locale);
String message = messageSource.getMessage("welcomeinfo", null, locale);
System.out.println(message);
return "login";
}
自定義區域信息解析器
public class MyLocaleResolver implements LocaleResolver {
// 解析區域信息
@Override
public Locale resolveLocale(HttpServletRequest req) {
Locale l = null;
String localeStr = req.getParameter("locale");
// 如果帶了locale參數,就用參數指定的信息,沒帶就用請求頭的
if (localeStr != null && !"".equals(localeStr)) {
// 將字符串切分
l = new Locale(localeStr.split("_")[0], localeStr.split("_")[1]);
} else {
l = req.getLocale();
}
return l;
}
// 設置區域信息
@Override
public void setLocale(HttpServletRequest arg0, HttpServletResponse arg1, Locale arg2) {
// 該異常模仿AcceptHeaderLocaleResolver
throw new UnsupportedOperationException(
"Cannot change HTTP accept header - use a different locale resolution strategy");
}
}
顯示頁面
<body>
<h1>
<fmt:message key="welcomeinfo"/>
</h1>
<form action="">
<fmt:message key="username"/>:<input/><br/>
<fmt:message key="password"/>:<input/><br/>
<input type="submit" value="<fmt:message key="loginBtn"/>">
</form>
<a href="tologinPage?locale=zh_CN">中文</a>|<a href="tologinPage?locale=en_US">English</a>
</body>
顯示頁面如下,點擊中/英文連接可以切換語言:
方式2:使用SessionLocaleResolver實現國際化
- 從請求參數中獲得locale的值,如果沒帶就用中文。即拿到代表區域信息的參數字符串後,包裝成一個Locale對象,放入Session中。
@Autowired
private ResourceBundleMessageSource messageSource;
@RequestMapping("/tologinPage")
public String tologinpage(@RequestParam(value = "locale", defaultValue = "zh_CN") String localeStr, Locale locale,
HttpSession session) {
System.out.println(locale);
String message = messageSource.getMessage("welcomeinfo", null, locale);
System.out.println(message);
Locale l = null;
// 如果帶了locale參數,就用參數指定的信息,沒帶就用默認的
if (localeStr != null && !"".equals(localeStr)) {
// 將字符串切分
l = new Locale(localeStr.split("_")[0], localeStr.split("_")[1]);
} else {
l = locale;
}
session.setAttribute(SessionLocaleResolver.class.getName() + ".LOCALE", l);
return "login";
}
配置Session區域信息解析器
- 區域信息從Session中拿
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
依然可以完成中英文切換
方式3:SessionLocaleResolver配合LocaleChangeInterceptor完成點擊鏈接國際化
- SpringMVC中配置LocaleChangeInterceptor和localeResolver。
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>
處理器
- 將處理器信息請求參數包裝成Locale的事情交給LocaleChangeInterceptor去做。
@Autowired
private ResourceBundleMessageSource messageSource;
@RequestMapping("/tologinPage")
public String tologinpage(String localeStr, Locale locale,
Model model, HttpSession session) {
System.out.println(locale);
String message = messageSource.getMessage("welcomeinfo", null, locale);
System.out.println(message);
return "login";
}
##SessionLocaleResolver&LocaleChangeInterceptor的工作原理
LocaleChangeInterceptor攔截器
幫我們完成的步驟:
①發請求時帶了一個區域信息參數叫做locale,其中指定了新的區域信息。
②獲得locale參數信息,將其解析爲Locale對象.
③將Locale對象放入LocaleResolver中。
LocaleChangeInterceptor還幫我們把區域信息Locale設置爲Session的屬性(裝入Session中)。
來到頁面後,可以使用SessionLocaleResolver區域信息解析器
獲取區域信息(從Session中獲取)。