SpringMVC(十五):国际化三种方案

star2017 1年前 ⋅ 257 阅读

  对开发者来说是国际化,对使用者来说是本地化。
  SpringMVC 的国际化是建立在Java国际化的基础之上,也是通过提供不同国家/语言环境的消息资源,然后通过ResourceBundle加载指定Local对应的资源文件,再取得该资源文件中指定key对应的消息。

国际化相关知识

Spring MVC 国际化步骤:

  1. 给系统加载国际化资源文件。
  2. 输出国际化。

Spring MVC 国际化消息有两种方式:

  1. 视图页面上输出国际化信息,需要使用SpringMVC的标签库。
  2. Controller 的处理方法中输出国际化信息,需要使用org.springframework.web.servlet.support.RequestContextgetMessage()方法来完成。

国际化的通用做法是通过读取用户浏览器请求头中Accept-Language属性值,该属性提供了关于用户浏览器的信息,根据该信息为用户选择语言区域;还可以根据HttpSession或者Cookie为用户选择语言区域。

Spring MVC 提供了一个语言区域解析接口LocalResolver,该接口的常用实现类都在org.springframework.web.servlet.i18n包下面,包括:

  1. AcceptHeaderLocaleResolver
  2. SessionLocaleResolver
  3. CookieLocaleResolver

基于浏览器请求的国际化实现

  基于浏览器请求的国际化即根据浏览器请求的消息头中的Accept-Language属性来选择区域性语言,默认装配 AcceptHeaderLocaleResolver来处理来解析语言区区域。
  AcceptHeaderLocaleResolver是默认的,是最容易使用的语言解析器,会读取浏览器的Accept-Language属性来确定使用哪个区域语言。该解析器不用显式配置。而sessioncookie需要手动显示配置。

示例代码

通过一个登录页面来演示Spring MVC 的国际化。

  1. 构建前端登录页面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>
    
  2. 构建登录成功后的返回页面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>
    
  3. 创建两个语言资源文件,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 = 管理员
    
  4. 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>
    
  5. 后端添加User实体类。

    public class User {
    
        private String username;
        private String loginname;
        private String password;
    
        --- set/get方法---
    }
    
  6. 后端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";
            }
        }
    }
    
  7. 验证国际化结果。
    切换浏览器的语言顺序,发送请求。

基于Session的国际化实现

显式配置SessionLocaleResolver语言解析器,会替换掉默认的AcceptHeaderLocaleResolver解析器。SpringMVC会从HttpSession域中获取用户所设置的语言来确定使用那个语言区域。

示例代码

  1. 前端添加用户可选择语言。
    两个超级链接,分别用于切换中文和英文语言环境,超级连接带参数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>
    
  2. 构建登录成功后的返回页面success.jsp
    同上:示例代码-2

  3. 添加区域语言资源文件
    同上: 示例代码-3

  4. 在文件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. 添加实体类
    同上:示例代码-5

  6. 后端代码识别用户选择的语言

    @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";
            }
        }
    }
    
  7. 验证
    单击超级链接,传递request_locale参数,后台根据该参数进行语言环境切换。

显式配置CookieLocaleResolver语言区域解析器,后台根据所选择的语言参数响应对应的语言环境。

示例代码

  1. 前端登录页面、成功页面、区域语言资源文件、实体类java文件同上。

  2. 在文件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>
    
  3. 后端代码识别用户选择的语言

     @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";
             }
         }
     }
    
  4. 验证语言切换
    点击超级链接切换语言环境,查看请求头和响应头中的Language参数值。

更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: