• Spring MVC之LocaleResolver详解


           对于LocaleResolver,其主要作用在于根据不同的用户区域展示不同的视图,而用户的区域也称为Locale,该信息是可以由前端直接获取的。通过这种方式,可以实现一种国际化的目的,比如针对美国用户可以提供一个视图,而针对中国用户则可以提供另一个视图。本文主要讲解如果使用LocaleResolver来实现对用户不同视图切换的目的。

           LocaleResolver是Spring提供的一个接口,其声明如下:

    public interface LocaleResolver {
        // 根据request对象根据指定的方式获取一个Locale,如果没有获取到,则使用用户指定的默认的Locale
    	Locale resolveLocale(HttpServletRequest request);
        
        // 用于实现Locale的切换。比如SessionLocaleResolver获取Locale的方式是从session中读取,但如果
        // 用户想要切换其展示的样式(由英文切换为中文),那么这里的setLocale()方法就提供了这样一种可能
    	void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, 
            @Nullable Locale locale);
    }
    

           针对LocaleResolver,Spring提供了几种实现方式,分别如下:

    • FixedLocaleResolver:在声明该resolver时,需要指定一个默认的Locale,在进行Locale获取时,始终返回该Locale,并且调用其setLocale()方法也无法改变其Locale;
    • CookieLocaleResolver:其读取Locale的方式是在session中通过Cookie来获取其指定的Locale的,如果修改了Cookie的值,页面视图也会同步切换;
    • SessionLocaleResolver:其会将Locale信息存储在session中,如果用户想要修改Locale信息,可以通过修改session中对应属性的值即可;
    • AcceptHeaderLocaleResolver:其会通过用户请求中名称为Accept-Language的header来获取Locale信息,如果想要修改展示的视图,只需要修改该header信息即可。

           需要说明的是,Spring虽然提供的几个不同的获取Locale的方式,但这些方式处理FixedLocaleResolver以外,其他几个也都支持在浏览器地址栏中添加locale参数来切换Locale。对于Locale的切换,Spring是通过拦截器来实现的,其提供了一个LocaleChangeInterceptor,在该拦截器中的preHandle()方法中,Spring会读取浏览器参数中的locale参数,然后调用LocaleResolver.setLocale()方法来实现对Locale的切换。

            这里我们以CookieLocaleResolver为例来讲解如何通过不同的Locale展示不同的视图。首先是我们的xml文件配置:

    <context:component-scan base-package="mvc"/>
    
      <mvc:annotation-driven/>
      <mvc:interceptors>
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
        <bean class="mvc.interceptor.MyHandlerInterceptor"/>
      </mvc:interceptors>
    
      <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver"/>
    
      <bean id="localeResolver" 
            class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="zh_CN"/>
      </bean>
    

           关于上述配置有三点需要说明:

    • 指定了使用的LocaleResolver为CookieLocaleResolver,并且defaultLocale指定为zh_CN,需要注意的是,Spring中LocaleResolver的bean名称必须为localeResolver,因为Spring读取该bean时是通过该名称读取的;
    • 上述配置总还指定了ViewResolver为ResourceBundleViewResolver,这里不能使用InternalResourceViewResolver,因为其不支持通过不同的Locale进行不同的视图切换,而ResourceBundleViewResolver是支持的;
    • 配置中添加了LocaleChangeInterceptor的拦截器,用于对Locale的切换,如果不需要Locale切换的功能,可以不指定该拦截器。

           对于后台接口的声明,其与一般的接口声明是没有区别的。如下是我们声明的一个接口:

    @Controller
    @RequestMapping("/user")
    public class UserController {
    
      @Autowired
      private UserService userService;
    
      @RequestMapping(value = "/detail", method = RequestMethod.GET)
      public ModelAndView detail(@RequestParam("id") long id, 
           @ModelAttribute("message") String message, Locale locale) {
        System.out.println(message);
        ModelAndView view = new ModelAndView("user");
        User user = userService.detail(id);
        view.addObject("user", user);
        view.addObject("locale", locale);
        return view;
      }
    }
    

           上述接口返回的视图为user,并且将当前用户的Locale信息返回给了前端,可以看到,这里获取Locale数据的方式就只需要简单的声明一个类型为Locale的参数即可。

           关于视图的展示,由于我们需要根据不同的Locale展示不同的视图,而在上述接口中,我们暂时没发现这样的路由。实际上,这个路由是通过ResourceBundleViewResolver类实现的,在使用该ViewResovler时,其会到class路径下查找名称为views的Resource Bundle,并且通过用户指定的Locale,唯一定位到某个Resource Bundle。然后在该Resource Bundle中查找指定的视图信息,比如这里接口返回的视图为user,那么就会在获取到的Resource Bundle查找user.(class)和user.url信息,这里user.(class)指定了展示该视图所需要的View对象的,而user.url则指定了具体的视图位置。比如如下配置的就是Locale分别为zh_CN和en_US的视图:

    # views_zh_CN.properties
    user.(class)=org.springframework.web.servlet.view.InternalResourceView
    user.url=/WEB-INF/view/user_zh_CN.jsp
    
    # views_en_US.properties
    user.(class)=org.springframework.web.servlet.view.InternalResourceView
    user.url=/WEB-INF/view/user_en_US.jsp
    

           通过这种方式,ResourceBundleViewResolver就实现了针对不同的Locale来展示不同的视图的目的。如下是我们编写的两个分别用于zh_CN和en_US视图展示的jsp页面:

    <!-- user_zh_CN.jsp -->
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>User Jsp-zh CN</title>
    </head>
    <body>
    ${user.id}&nbsp;&nbsp;${user.name}&nbsp;&nbsp;${user.age}&nbsp;&nbsp;${locale}
    </body>
    </html>
    
    <!-- user_en_US.jsp -->
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>User Jsp-en US</title>
    </head>
    <body>
    ${user.id}&nbsp;&nbsp;${user.name}&nbsp;&nbsp;${user.age}&nbsp;&nbsp;${locale}
    </body>
    </html>
    

           启动上述程序,我们在浏览器中键入http://localhost:8080/user/detail?id=1,可以看到其展示了如下视图:

    1  Bob  27  zh_CN
    

           如果我们添加名称为org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE,值为en_US的cookie,那么其展示的页面切换如下:

    1  Bob  27  en_US
    

           这说明我们成功使用Cookie对Locale进行了切换。如果我们在浏览器地址栏中添加locale=zh_CN的参数,可以看到,页面展示又切换为了前面那种情况。

           本文主要对LocaleResolver进行了讲解,并且演示了如何通过配置不同的LocaleResolver来达到实现展示不同的视图的目的。需要注意的是,我们的LocaleResolver的bean名称必须为localeResolver,并且需要指定的ViewResolver辅以支持,否则切换的视图可能无法正常工作。

    转载于:https://my.oschina.net/zhangxufeng/blog/2222918

  • 相关阅读:
    Python SOCKET网络编程
    网络基础 -- 子网划分
    网络基础 -- 网络协议篇
    面向对象练习:学生选课系统
    python 异常处理 断言
    Python 面向对象 中高级
    Python 面向对象 基础
    Python 练习
    Python 练习计算器
    Python 正则表达式
  • 原文地址:https://www.cnblogs.com/twodog/p/12135845.html
Copyright © 2020-2023  润新知