SpringMVC框架 |i18n國際化


使用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中獲取)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章