SonicsTorm 2019-06-27
根据客户端环境,界面显示不同的国旗图案。
在接到一个需求时,首先要理解需求,实际工作中可能需求跟产品进行多次沟通,其目的就是准确的理解,理解了需求就可以选择相应的技术方案去解决。就我们这个功能来说,需求就是可定制不同的国旗图案。选择的技术方案可利用Spring MVC提供的国际化和主题定制来解决。
源码分析
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,结果如下:
由图可知,此时系统使用的是默认的国际化属性文件及显示默认的国旗图案,与我们设想的一致。注意此时返回的cookie中没有国际化及主题相关的信息。
2、通过请求参数locale
设置地区环境,在地址栏输入localhost:8088/demo?locale=en_US,并发起请求,结果如下:
由上图可知结果,与我们的设想一致,并且服务端通过拦截器把国际化写入了客户端cookie中。
3、修改请求参数locale
的值为荷兰,即locale=sv_FI后再发起请求,结果如下:
与预期一致,测试通过。
本例使用CookieLocaleResolver和CookieThemeResolver结合实现了国际化与主题定制需求,Spring MVC为我们提供了不通实现方式的LocaleResolver和ThemeResolver,可自由组合使用,这两个策略解析器主要定制前端信息或样式,通过之前的源码分析及此案例,这块内容就分析完了,希望对大家有所帮助。
最后创建了qq群方便大家交流,可扫描加入,同时也可加我qq:276420284,共同学习、共同进步,谢谢!