SpringMVC之源码分析--LocaleResolver和ThemeResolver应用

概述

需求

根据客户端环境,界面显示不同的国旗图案。

分析

在接到一个需求时,首先要理解需求,实际工作中可能需求跟产品进行多次沟通,其目的就是准确的理解,理解了需求就可以选择相应的技术方案去解决。就我们这个功能来说,需求就是可定制不同的国旗图案。选择的技术方案可利用Spring MVC提供的国际化和主题定制来解决。

实现

  • 项目结构

SpringMVC之源码分析--LocaleResolver和ThemeResolver应用

  • 源码分析

    • pom.xml文件

      引入Spring MVC依赖以及JSP依赖,代码如下:

      <!-- Spring MVC依赖 -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.0.5.RELEASE</version>
      </dependency>
      <dependency>
      <!-- Servlet支持 -->
      <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
      </dependency>
      <!-- jsp支持-->
      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
      </dependency>
    • spring-servlet.xml文件

      在classpath下新建Spring MVC配置文件,代码如下:

      <!-- 启动注解扫描 -->
      <mvc:annotation-driven/>
      
       <!-- mvc controller -->
      <context:component-scan base-package="com.github.dalianghe.controller" />
      
      <!-- 默认Servlet处理静态资源 -->
      <mvc:default-servlet-handler />
      
      <!-- jsp视图映射与视图解析 -->
      <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
          <property name="prefix" value="/WEB-INF/jsp/"/>
          <property name="suffix" value=".jsp"/>
      </bean>
      
      <mvc:interceptors>
          <!-- 该拦截器通过参数名为”locale”的参数来拦截HTTP请求,设置LocaleResolver -->
          <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
              <property name="paramName" value="locale"/>
          </bean>
      </mvc:interceptors>
      
      <!-- 国际化资源文件 -->
      <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
          <!-- 如果资源文件放在classpath下,basename的value必须有classpath:前缀,否则报错:No message found under code... -->
          <property name="basename" value="classpath:i18n/messages" />
          <!-- 如果在国际化资源文件中找不到对应代码的信息,就用这个代码作为名称返回  -->
          <property name="useCodeAsDefaultMessage" value="true" />
      </bean>
      
       <!--CookieLocaleResolver解析器 -->
      <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
          <!-- 设置默认为中国,即从客户端cookie中未找到cookieName时,使用默认locale -->
          <property name="defaultLocale" value="zh_CN"/>
          <!-- 设置cookieName,默认为:org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE -->
          <property name="cookieName" value="locale"/>
      </bean>
      
      <!-- 加载主题资源文件 -->
      <bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource">
          <!-- 指定文件前缀,即文件所在目录,如果放在classpath下,value为空(默认从classpath下加载) -->
          <property name="basenamePrefix" value="theme."/>
      </bean>
      
      <!-- 主题解析器 -->
      <bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver">
          <!-- 主题文件名称,如果有多个相同前缀(theme)时,
                 查找最终的文件名为: defaultThemeName+国际化标识,如:theme_zh_CN.properties-->
          <property name="defaultThemeName" value="theme"/>
          <!-- 设置theme的客户端cookie名 -->
          <property name="cookieName" value="theme"/>
      </bean>
    • web.xml文件

      配置Spring MVC 前端控制器,即DispatcherServlet,负责拦截用户请求,代码如下:

      <servlet>
          <!-- Servlet名称,可任意定义,但必须与servlet-mapping中对应 -->
          <servlet-name>dispatcher</servlet-name>
          <!-- 指定Spring MVC核心控制类,即J2EE规范中的前端控制器(Front Controller) -->
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <!-- 指定Spring MVC配置文件,默认在WEB-INF目录下,
              切名字为[servlet-name]-servlet.xml,此文件中配置web相关内容,
              比如:指定扫描Controller路径、配置逻辑视图前缀后缀、上传文件等等 -->
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:spring-servlet.xml</param-value>
          </init-param>
          <!-- 此配置的值为正整数时,表示容器启动时初始化,即调用Servlet的init方法 -->
          <load-on-startup>1</load-on-startup>
          <async-supported>true</async-supported>
      </servlet>
      <!-- 定义servlet映射 -->
      <servlet-mapping>
          <!-- 与servlet中servlet-name对应 -->
          <servlet-name>dispatcher</servlet-name>
          <!-- 映射所有的url -->
          <url-pattern>/</url-pattern>
      </servlet-mapping>
    • 国际化属性文件

      本例中创建了中国、美国及芬兰的国际化支持,配置文件如下:

      messages_zh _CN.properties

      message.locale=中国

      messages_en _US.properties

      message.locale=美国

      messages_sv _FI.properties

      message.locale=芬兰
    • 主题属性文件

      根据国际化配置,主题定义了中国、美国及芬兰的国旗图片,配置如下:

      theme_ zh_CN.properties

      background=/img/China.jpg

      theme_ en_US.properties

      background=/img/America.jpg

      theme_ sv_FI.properties

      background=/img/Finland.jpg
    • 视图及控制器

      Controller控制器代码如下:

      @RequestMapping("/demo")
      public String demo(HttpServletRequest request , Model model){
      
          Locale locale = RequestContextUtils.getLocale(request);
      
          model.addAttribute("locale",locale);
      
          return "demo";
      }

      JSP视图代码如下:

      <%@ page contentType="text/html;charset=UTF-8" %>
      <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
      <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
      <html>
          <head>
          <title>Spring MVC Theme</title>
          </head>
          <body>
              <fmt:message key="message.name"/> : <fmt:message key="message.locale"/>
              <br/><br/>
              <img src="<spring:theme code='background'/>" style="width: 500px;height: 300px;">
          </body>
      </html>
  • 功能测试

本例以Firefox为客户端测试工具,测试步骤如下:

1、启动项目后,访问界面,在地址栏输入http://localhost:8088/demo,结果如下:

SpringMVC之源码分析--LocaleResolver和ThemeResolver应用

由图可知,此时系统使用的是默认的国际化属性文件及显示默认的国旗图案,与我们设想的一致。注意此时返回的cookie中没有国际化及主题相关的信息。

2、通过请求参数locale设置地区环境,在地址栏输入localhost:8088/demo?locale=en_US,并发起请求,结果如下:

SpringMVC之源码分析--LocaleResolver和ThemeResolver应用

由上图可知结果,与我们的设想一致,并且服务端通过拦截器把国际化写入了客户端cookie中。

3、修改请求参数locale的值为荷兰,即locale=sv_FI后再发起请求,结果如下:

SpringMVC之源码分析--LocaleResolver和ThemeResolver应用

与预期一致,测试通过。

总结

本例使用CookieLocaleResolver和CookieThemeResolver结合实现了国际化与主题定制需求,Spring MVC为我们提供了不通实现方式的LocaleResolver和ThemeResolver,可自由组合使用,这两个策略解析器主要定制前端信息或样式,通过之前的源码分析及此案例,这块内容就分析完了,希望对大家有所帮助。

最后创建了qq群方便大家交流,可扫描加入,同时也可加我qq:276420284,共同学习、共同进步,谢谢!

SpringMVC之源码分析--LocaleResolver和ThemeResolver应用

相关推荐