Spring MVC 之 DispatcherServlet之国际环境

1.messageSource接口
2.localeResolver接口
3.message标签
4.AcceptHeaderLocaleResolver国际化
5.SessionLocaleResolver国际化
6.CookieLocaleResolver国际化

springmvc国际化步骤
1.给系统加载国际化资源文件
2.输出国际化
方式一:在视图页面上输出国际化消息,需要使用springmvc标签库
方式二:在Controller的处理方法中输出国际化消息,需要使用org.springframework.web.servlet.support.RequestContext的getMessage()方法来完成

为用户选择语言区域时,最常用的方法是通过读取用户浏览器的accept-language标题值,accept-language提供了关于用户浏览器语言的信息。选择语言区域的其他方法还包括读取HttpSession或则Cookie

springmvc提供了一个语言区域解析器接口LocaleResolver,该接口的常用实现类都在org.springframework.web.servlet.i18n下面包括:
AcceptHeaderLocaleResolver(默认,可以不用显示配置)
SessionLocaleResolver(需要显示配置)
CookieLocaleResolver(需要显示配置)

message标签:
需要在jsp页面添加
<%@taglib prefix=”spring” uri=”http://www.springframework.org/tags” %>

在这里插入图片描述
案例一:
配置两个资源文件
文件名为:[springmvc配置文件中的value值]_zh_CN.properties
eg:
fkit_en_US.properties
fkit_zh_CN.properties

fkit_en_US.properties内容为:

name= Login name:
password = Password:
submit = Submit
welcome = Welcom {0} access fkit
title = Login Page
username = administrator

fkit_zh_CN.properties内容为

name= \u767B\u5F55\u540D:
password = \u5BC6\u7801:
submit = \u63D0\u4EA4
welcome = \u6B22\u8FCE {0} springmvc test
title = \u767B\u5F55\u9875\u9762
username = \u7BA1\u7406\u5458

在springmvc的配置文件中配置
下面的中的value值与上面资源文件名称相对应

<!-- 自动注册组件 -->
    <mvc:annotation-driven /> 
    <!-- 使用默认的Servlet来响应静态文件 -->
    <!-- <mvc:default-servlet-handler /> -->


    <!-- 扫包 ,将所有spring的注解注册成bean -->
    <context:component-scan base-package="com.**"></context:component-scan>
    <!-- 配置annotation类型的处理映射器 -->
    <bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
    <!-- 配置annotation类型处理器适配器 -->
    <bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>

    <!-- 配置视图解析器 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!-- 在index.jsp页面配置静态资源文件的路径时 可以使用${basePath} -->
    <bean id="bresource" class="com.core.TmBasePathExposer" init-method="init"></bean>

    <!-- 利用messageSource告诉springmvc国际化的属性文件保存在哪里 -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <!-- basenames属性来指定国际化的属性文件名称 -->
        <property name="basenames">
            <list>
                <value>message</value>
                <value>fkit</value>
            </list>
        </property>
    </bean>
        <mvc:interceptors>  
        <!-- 国际化操作拦截器 如果采用基于(Session/Cookie)则必需配置 --> 
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />  
    </mvc:interceptors>  

    <!-- AcceptHeaderLocaleResolver 配置,因为AcceptHeaderLocaleResolver是默认语言区域解析器,不配置也可以  -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" /> 

实体代码:

package com.entity;

public class User {
    private String name;
    private String password;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

}

访问http://localhost:8080/springmvcNote1/internation/loginForm
进入loginForm方法转到login.jsp页面

@Controller
@RequestMapping("internation")
public class InternationalController {
    //  http://localhost:8080/springmvcNote1/internation/loginForm
    @RequestMapping("loginForm")
    public String loginForm(Model model){
        User user = new User();
        model.addAttribute("user",user);
        return "Internationalization/login";
    }

login.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>aaaa
    <!-- 使用message标签来输出国际化信息 -->
     <h3><spring:message code="title"/></h3>
    <form:form modelAttribute="user" method="post" action="login">
        <table>
        <tr>
            <td><spring:message code="name"/></td>
            <td><form:input path="name"/></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>

点击提交转到

@RequestMapping("login")
    public String test01(@ModelAttribute @Validated User user
            ,Model model,HttpServletRequest request){

        if(user.getPassword()!=null && user.getName()!=null
                && user.getName().equals("caoxuekun")
                && user.getPassword().equals("123")){
            System.out.println("****************");
            //从后台代码获取国际化信息username
            RequestContext requestContext = new RequestContext(request);
            String name = requestContext.getMessage("name");

            //将获取的username信息设置到user对象,并设置到model中
            user.setName(name);
            model.addAttribute("user",user);
            return "/Internationalization/success";
        }
        return "Internationalization/error";
    }

如果输入的用户名和密码分别为caoxuekun和123那么跳转到success.jsp页面,否则跳转到error.jsp页面
效果:
在这里插入图片描述
在这里插入图片描述
改变浏览器的语言(下面对应的是火狐)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
SessionLocaleResolver国际化:
不是默认语言区域解析器,需要显示配置,springmvc会从HttpSession作用域中获取用户所设置的语言区域。
案例
springmv中的配置文件

<!-- 利用messageSource告诉springmvc国际化的属性文件保存在哪里 -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <!-- basenames属性来指定国际化的属性文件名称 -->
        <property name="basenames">
            <list>
                <value>message</value>
                <value>fkit</value>
            </list>
        </property>
    </bean>
        <mvc:interceptors>  
        <!-- 国际化操作拦截器 如果采用基于(Session/Cookie)则必需配置 --> 
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />  
    </mvc:interceptors>  

    <!-- AcceptHeaderLocaleResolver 配置,因为AcceptHeaderLocaleResolver是默认语言区域解析器,不配置也可以  -->
    <!-- <bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" />  -->

    <!-- SessionLocaleResolver 配置 -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" /> 

访问:localhost:8080/springmvcNote1/internation/sessionLogin
进入sessionLogin方法转到sessionLogin.jsp页面

@RequestMapping(value="/sessionLogin")
     public String sessionLogin(
             String request_locale,
             Model model,
             HttpServletRequest request){
        System.out.println("request_locale = " + request_locale);
        if(request_locale != null){
            // 设置中文环境
            if(request_locale.equals("zh_CN")){
                Locale locale = new Locale("zh", "CN"); 
               request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,locale); 
            }
            // 设置英文环境
            else if(request_locale.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 "Internationalization/sessionLogin";
    }

sessionLogin.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>测试基于SessionLocaleResolver的国际化</title>
</head>
<body>
<!-- 用户可以选择切换语言环境 -->
<a href="sessionLogin?request_locale=zh_CN">中文</a> | <a href="sessionLogin?request_locale=en_US">英文</a>
<br/>
<h3><spring:message code="title"/></h3>
<form:form modelAttribute="user" method="post" action="login" >
    <table>
        <tr>
            <td><spring:message code="name"/></td>
            <td><form:input path="name"/></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>

点击提交跳转到test01方法,如果登陆名和密码为caoxuekun和123
那么跳转到success.jsp否则error.jsp

@RequestMapping("login")
    public String test01(@ModelAttribute @Validated User user
            ,Model model,HttpServletRequest request){

        if(user.getPassword()!=null && user.getName()!=null
                && user.getName().equals("caoxuekun")
                && user.getPassword().equals("123")){
            //从后台代码获取国际化信息username
            RequestContext requestContext = new RequestContext(request);
            String name = requestContext.getMessage("name");

            //将获取的username信息设置到user对象,并设置到model中
            user.setName(name);
            model.addAttribute("user",user);
            return "/Internationalization/success";
        }
        return "Internationalization/error";
    }

success.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <spring:message code="welcome" arguments="${requestScope.user.name}"/>
</body>
</html>

实体类

package com.entity;

public class User {
    private String name;
    private String password;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

}

CookieLocaleResolver国际化
案例
springmvc配置文件

 <mvc:annotation-driven /> 
    <!-- 使用默认的Servlet来响应静态文件 -->
    <!-- <mvc:default-servlet-handler /> -->


    <!-- 扫包 ,将所有spring的注解注册成bean -->
    <context:component-scan base-package="com.**"></context:component-scan>
    <!-- 配置annotation类型的处理映射器 -->
    <bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
    <!-- 配置annotation类型处理器适配器 -->
    <bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>

    <!-- 配置视图解析器 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!-- 在index.jsp页面配置静态资源文件的路径时 可以使用${basePath} -->
    <bean id="bresource" class="com.core.TmBasePathExposer" init-method="init"></bean>

    <!-- 利用messageSource告诉springmvc国际化的属性文件保存在哪里 -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <!-- basenames属性来指定国际化的属性文件名称 -->
        <property name="basenames">
            <list>
                <value>message</value>
                <value>fkit</value>
            </list>
        </property>
    </bean>
        <mvc:interceptors>  
        <!-- 国际化操作拦截器 如果采用基于(Session/Cookie)则必需配置 --> 
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />  
    </mvc:interceptors>  

    <!-- AcceptHeaderLocaleResolver 配置,因为AcceptHeaderLocaleResolver是默认语言区域解析器,不配置也可以  -->
    <!-- <bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" />  -->

    <!-- SessionLocaleResolver 配置 -->
    <!-- <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />  -->

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

访问:http://localhost:8080/springmvcNote1/internation/cookieLogin
进入cookieLogin方法,跳转到cookieLogin.jsp页面

@RequestMapping(value="cookieLogin")
     public String cookieLogin(
             String request_locale,
             Model model,
             HttpServletRequest request,
             HttpServletResponse response){
        System.out.println("request_locale = " + request_locale);
        if(request_locale != null){
            if(request_locale.equals("zh_CN")){
                Locale locale = new Locale("zh", "CN"); 
                (new CookieLocaleResolver()).setLocale (request, response, locale);
            }
            else if(request_locale.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 "Internationalization/cookieLogin";
    }

cookieLogin.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>测试基于SessionLocaleResolver的国际化</title>
</head>
<body>
<!-- 用户可以选择切换语言环境 -->
<a href="cookieLogin?request_locale=zh_CN">中文</a> | <a href="cookieLogin?request_locale=en_US">英文</a>
<br/>
<h3><spring:message code="title"/></h3>
<form:form modelAttribute="user" method="post" action="login" >
    <table>
        <tr>
            <td><spring:message code="name"/></td>
            <td><form:input path="name"/></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>

提交跳转到test01方法,登陆成功进入success.jsp页面,否则进入error.jsp页面

@RequestMapping("login")
    public String test01(@ModelAttribute @Validated User user
            ,Model model,HttpServletRequest request){

        if(user.getPassword()!=null && user.getName()!=null
                && user.getName().equals("caoxuekun")
                && user.getPassword().equals("123")){
            //从后台代码获取国际化信息username
            RequestContext requestContext = new RequestContext(request);
            String name = requestContext.getMessage("name");

            //将获取的username信息设置到user对象,并设置到model中
            user.setName(name);
            model.addAttribute("user",user);
            return "/Internationalization/success";
        }
        return "Internationalization/error";
    }

本文来自 caoxuekun 的CSDN 博客 ,全文地址请点击:
https://blog.csdn.net/caoxuekun/article/details/76577096?utm_source=copy

   <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    
        <!-- 根据具体情况自定义 -->
        <property name="cookieName" value="clientlanguage"/>
    
        <!-- 100000 为秒数,值为 -1 时, cookie 会在浏览器关闭时被销毁 -->
        <property name="cookieMaxAge" value="100000"/>
    
    </bean>
  --对clientlanguage的理解,即前端传送的cookie name为clientlanguage,
    
        if(clientlanguage.equals("zh_cn")){
                        resolver.setLocale(request, response, Locale.CHINA );
                    }else if(language.equals("en")){
                        resolver.setLocale(request, response, Locale.ENGLISH );
                    }else{
                        resolver.setLocale(request, response, Locale.CHINA );
                    }
具体可参考: https://www.cnblogs.com/flying607/p/4698949.html

时区

除了语言环境,有时还需要获得客户端的时区信息,LocaleContextResolver 对 LocaleResolver 中的功能进行了扩展,这样可以在 LocaleContext 中获得更为丰富的信息。

通过 RequestContext.getTimeZone()方法获取客户端的时区信息,在 Spring 的 ConversionService 中注册的日期/时间转换器和格式化器会自动获取这些信息。

—对于时区的理解,可参考:https://segmentfault.com/a/1190000014813287
CookieLocaleResolver继承CookieGenerator并实现LocaleContextResolver接口,CookieGenerator主要是操作Cookie的工具类,LocaleContextResolver继承LacleResovler接口,增加了TimeZone信息操作。即通过Cookie实现Locale的选择。

CookieLocaleResolver类的入口是resolveLocaleContext(final HttpServletRequest request),即Spring MVC接收到客户端请求后,会调用此方法,源码如下:

public void setLocaleContext(HttpServletRequest request, @Nullable HttpServletResponse response,
        @Nullable LocaleContext localeContext) {

    Assert.notNull(response, "HttpServletResponse is required for CookieLocaleResolver");

    Locale locale = null;
    TimeZone timeZone = null;
    if (localeContext != null) {
        locale = localeContext.getLocale();
        if (localeContext instanceof TimeZoneAwareLocaleContext) {
            timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();
        }
        addCookie(response,
                (locale != null ? toLocaleValue(locale) : "-") + (timeZone != null ? ' ' + timeZone.getID() : ""));
    }
    else {
        removeCookie(response);
    }
    request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,
            (locale != null ? locale : determineDefaultLocale(request)));
    request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,
            (timeZone != null ? timeZone : determineDefaultTimeZone(request)));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值