Spring MVC之LocaleResolver详解

       对于LocaleResolver,其主要做用在于根据不一样的用户区域展现不一样的视图,而用户的区域也称为Locale,该信息是能够由前端直接获取的。经过这种方式,能够实现一种国际化的目的,好比针对美国用户能够提供一个视图,而针对中国用户则能够提供另外一个视图。本文主要讲解若是使用LocaleResolver来实现对用户不一样视图切换的目的。html

       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提供了几种实现方式,分别以下:java

  • 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的切换。web

        这里咱们以CookieLocaleResolver为例来说解如何经过不一样的Locale展现不一样的视图。首先是咱们的xml文件配置:spring

<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切换的功能,能够不指定该拦截器。

       对于后台接口的声明,其与通常的接口声明是没有区别的。以下是咱们声明的一个接口:cookie

@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的参数便可。session

       关于视图的展现,因为咱们须要根据不一样的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的视图:mvc

# 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页面:app

<!-- 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辅以支持,不然切换的视图可能没法正常工做。

相关文章
相关标签/搜索