对开发者来说是国际化,对使用者来说是本地化。
SpringMVC 的国际化是建立在Java国际化的基础之上,也是通过提供不同国家/语言环境的消息资源,然后通过ResourceBundle
加载指定Local
对应的资源文件,再取得该资源文件中指定key
对应的消息。
国际化相关知识
Spring MVC 国际化步骤:
- 给系统加载国际化资源文件。
- 输出国际化。
Spring MVC 国际化消息有两种方式:
- 视图页面上输出国际化信息,需要使用
SpringMVC
的标签库。 - 在
Controller
的处理方法中输出国际化信息,需要使用org.springframework.web.servlet.support.RequestContext
的getMessage()
方法来完成。
国际化的通用做法是通过读取用户浏览器请求头中Accept-Language
属性值,该属性提供了关于用户浏览器的信息,根据该信息为用户选择语言区域;还可以根据HttpSession
或者Cookie
为用户选择语言区域。
Spring MVC 提供了一个语言区域解析接口LocalResolver
,该接口的常用实现类都在org.springframework.web.servlet.i18n
包下面,包括:
- AcceptHeaderLocaleResolver
- SessionLocaleResolver
- CookieLocaleResolver
基于浏览器请求的国际化实现
基于浏览器请求的国际化即根据浏览器请求的消息头中的Accept-Language
属性来选择区域性语言,默认装配 AcceptHeaderLocaleResolver
来处理来解析语言区区域。
AcceptHeaderLocaleResolver
是默认的,是最容易使用的语言解析器,会读取浏览器的Accept-Language
属性来确定使用哪个区域语言。该解析器不用显式配置。而session
和cookie
需要手动显示配置。
示例代码
通过一个登录页面来演示Spring MVC 的国际化。
构建前端登录页面
loginForm.jsp
,引入spring
标签库。<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>基于浏览器的国际化</title> </head> <body> <h3><spring:message code = "title" /></h3> <form:form action="/springmvc_01_2/user/login" method="post" modelAttribute="user"> <table> <tr> <td><spring:message code="loginname" /></td> <td><form:input path="loginname" /></td> </tr> <tr> <td><spring:message code="password" /></td> <td><form:input path="password" /></td> </tr> <tr> <td><input type="submit" value="<spring:message code="submit" />" /></td> </tr> </table> </form:form> </body> </html>
构建登录成功后的返回页面
success.jsp
。<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>登录成功</title> </head> <body> <spring:message code="welcome" arguments="${requestScope.user.username}" /> </body> </html>
创建两个语言资源文件,
properties
文件,UTF-8
编码; 此两个文件放到项目资源目录(config
)里。//文件名:message_en_US.properties loginname = Login name: password = Password: submit = Submit welcome = Welcome {0} access this website title = Login Page username = admin //文件名:message_zh_CN.properties loginname = 登录名: password = 密码: submit = 提交 welcome = 欢迎 {0} 访问本站 title = 登录页面 username = 管理员
springmvc.xml
配置文件添加bean
,告诉那些是语言资源文件。<!-- 国际化 : 根据value查找以该值开头的.properties资源文件 资源文件名构造:value值_请求语言.properties --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <!-- 国际化资源文件名, 要以配置多个值 --> <property name="basenames"> <list> <value>message</value> <!-- <value>language</value> --> </list> </property> <!-- 支持UTF-8的中文 --> <property name="cacheSeconds" value="0"/> <property name="defaultEncoding" value="UTF-8"/> </bean> <!-- 拦截器配置 --> <mvc:interceptors> <!-- 国际化操作拦截器 --> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors>
后端添加
User
实体类。public class User { private String username; private String loginname; private String password; --- set/get方法--- }
后端
Controller
层添加处理方法。@Controller @RequestMapping("/user") public class LoginController { @RequestMapping("/loginV") public String loginView(Model model) { User user = new User(); model.addAttribute("user", user); return "loginForm"; } @RequestMapping(value = "/login", method = { RequestMethod.POST }) public String login(@ModelAttribute @Validated User user, HttpServletRequest request, Model model) { String loginName = user.getLoginname(); String password = user.getPassword(); if (loginName != null && loginName.equals("root") && password != null && password.equals("root123")) { RequestContext requestContext = new RequestContext(request); String username = requestContext.getMessage("username"); user.setUsername(username); model.addAttribute("user", user); return "success"; }else { return "error"; } } }
验证国际化结果。
切换浏览器的语言顺序,发送请求。
基于Session的国际化实现
显式配置SessionLocaleResolver
语言解析器,会替换掉默认的AcceptHeaderLocaleResolver
解析器。SpringMVC会从HttpSession
域中获取用户所设置的语言来确定使用那个语言区域。
示例代码
前端添加用户可选择语言。
两个超级链接,分别用于切换中文和英文语言环境,超级连接带参数request_local
,传递语言类型。<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>基于浏览器的国际化</title> </head> <body> <a href="${pageContext.request.contextPath}/user/loginV?request_local=zh_CN">中文</a> | <a href="${pageContext.request.contextPath}/user/loginV?request_local=en_US">English</a> <h3><spring:message code = "title" /></h3> <form:form action="/springmvc_01_2/user/login" method="post" modelAttribute="user"> <table> <tr> <td><spring:message code="loginname" /></td> <td><form:input path="loginname" /></td> </tr> <tr> <td><spring:message code="password" /></td> <td><form:input path="password" /></td> </tr> <tr> <td><input type="submit" value="<spring:message code="submit" />" /></td> </tr> </table> </form:form> </body> </html>
构建登录成功后的返回页面
success.jsp
。
同上:示例代码-2添加区域语言资源文件
同上: 示例代码-3在文件
springmvc.xml
里显式配置SessionLocaleResolver
。<!-- 显式配置SessionLocaleResolver语言解析器, 替换掉默认的localResolver --> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean> <!-- 国际化 : 根据value查找以该值开头的.properties资源文件 资源文件名构造:value值_请求语言.properties --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <!-- 国际化资源文件名, 要以配置多个值 --> <property name="basenames"> <list> <value>message</value> <!-- <value>language</value> --> </list> </property> <!-- 支持UTF-8的中文 --> <property name="cacheSeconds" value="0"/> <property name="defaultEncoding" value="UTF-8"/> </bean> <mvc:interceptors> <!-- 国际化操作拦截器 --> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors>
添加实体类
同上:示例代码-5后端代码识别用户选择的语言
@Controller @RequestMapping("/user") public class LoginController { @RequestMapping("/loginV") public String loginView(Model model, String request_local, HttpServletRequest request) { if (request_local != null) { if (request_local.equals("zh_CN")) { //中文环境 Locale locale = new Locale("zh", "CN"); request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale); } else if (request_local.equals("en_US")) { //英文环境 Locale locale = new Locale("en", "US"); request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale); } else { //默认环境 request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, LocaleContextHolder.getLocale()); } } User user = new User(); model.addAttribute("user", user); return "loginForm"; } @RequestMapping(value = "/login", method = { RequestMethod.POST }) public String login(@ModelAttribute @Validated User user, HttpServletRequest request, Model model) { String loginName = user.getLoginname(); String password = user.getPassword(); if (loginName != null && loginName.equals("admin") && password != null && password.equals("123")) { RequestContext requestContext = new RequestContext(request); String username = requestContext.getMessage("username"); user.setUsername(username); model.addAttribute("user", user); return "success"; } else { return "error"; } } }
验证
单击超级链接,传递request_locale
参数,后台根据该参数进行语言环境切换。
基于Cookie的国际化实现
显式配置CookieLocaleResolver
语言区域解析器,后台根据所选择的语言参数响应对应的语言环境。
示例代码
前端登录页面、成功页面、区域语言资源文件、实体类java文件同上。
在文件
springmvc.xml
里显式配置CookieLocaleResolver
。<!-- 显式配置SessionLocaleResolver语言解析器, 替换掉默认的localResolver --> <!-- <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean> --> <!-- 显式配置CookieLocaleResolver语言解析器, 替换掉默认的localResolver --> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"></bean> <!-- 国际化 : 根据value查找以该值开头的.properties资源文件 资源文件名构造:value值_请求语言.properties --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <!-- 国际化资源文件名, 要以配置多个值 --> <property name="basenames"> <list> <value>message</value> <!-- <value>language</value> --> </list> </property> <!-- 支持UTF-8的中文 --> <property name="cacheSeconds" value="0"/> <property name="defaultEncoding" value="UTF-8"/> </bean> <mvc:interceptors> <!-- 国际化操作拦截器 --> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors>
后端代码识别用户选择的语言
@Controller @RequestMapping("/user") public class LoginController { @RequestMapping("/loginV") public String loginView(Model model, String request_local, HttpServletRequest request, HttpServletResponse response) { if (request_local != null) { if (request_local.equals("zh_CN")) { //中文环境 Locale locale = new Locale("zh", "CN"); (new CookieLocaleResolver()).setLocale(request, response, locale); } else if (request_local.equals("en_US")) { //英文环境 Locale locale = new Locale("en", "US"); (new CookieLocaleResolver()).setLocale(request, response, locale); } else { //默认环境 (new CookieLocaleResolver()).setLocale(request, response, LocaleContextHolder.getLocale()); } } User user = new User(); model.addAttribute("user", user); return "loginForm"; } @RequestMapping(value = "/login", method = { RequestMethod.POST }) public String login(@ModelAttribute @Validated User user, HttpServletRequest request, Model model) { String loginName = user.getLoginname(); String password = user.getPassword(); if (loginName != null && loginName.equals("admin") && password != null && password.equals("123")) { RequestContext requestContext = new RequestContext(request); String username = requestContext.getMessage("username"); user.setUsername(username); model.addAttribute("user", user); return "success"; } else { return "error"; } } }
验证语言切换
点击超级链接切换语言环境,查看请求头和响应头中的Language
参数值。
注意:本文归作者所有,未经作者允许,不得转载