1.springmvc-servlet.xml中的内容
<context:component-scan base-package="com.wiley.beginningspring.ch3" />
<context:annotation-config />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource"/>
<bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver">
<property name="defaultThemeName" value="dark" />
</bean>
<mvc:interceptors>
<bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
<property name="paramName" value="theme"/>
</bean>
</mvc:interceptors>
主题架构最核心的三个机制themeSource、themeResolver、themeChangeInterceptor。
themeSource是什么?专门读取路径中的属性文件,比如dark.properties,文件的格式是键值对形式,比如style=css/dark.css
themeResolver干什么的?当然是将主题文件进行处理啊,解析啊。
themeChangeInterceptor呢?切换主题的作用。
2.项目目录结构
//项目源代码
@Controller
public class FormController {
@RequestMapping(value = "/form")
public ModelAndView user() {
return new ModelAndView("form", "user", new User());
}
@RequestMapping(value = "/result")
public ModelAndView processUser(User user) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("u", user);
modelAndView.setViewName("result");
return modelAndView;
}
}
三者的分工不同,themeSource拿到很多主题资源,themeChangeInterceptor选择主题资源,themeResolver处理主题资源。具体又是怎么走的呢?看form.jsp代码中涉及到主题切换的一段代码:
<head>
<title>Spring MVC Themes</title>
<!-- 属性文件中定义的键值 -->
<link rel="stylesheet" href="<spring:theme code="style"/>" type="text/css" />
</head>
<body>
Theme :
<a href="?theme=light">Light</a> - <a href="?theme=dark">Dark</a>
<br/>
</body>
首先看<link rel=“stylesheet” href="<spring:theme code=“style”/>" type=“text/css” />,这一段明显是引入主题资源的。可问题是没有看到主题资源包,以前引入.css,.js文件,那可是明明白白写清楚资源路径是啥,要引入的资源名。由themeSource找到资源,只有他找到了资源,才可以用啊。问题是themeSource是怎么找到资源的呢?themeSource创建时,他就会去寻找属性文件并且加载资源。可是<spring:theme code=“style”/>他就是资源啊。是资源列表啊。加载的资源是以键值对的形式存在,此时的style好比如列表名。因为两个属性文件中的内容是style=css/dark.css和style=css/light.css。显然,此时的列表中有两个元素[css/dark.css, css/light.css]。默认情况下使用css/dark.css。因为springmvc-servlet.xml中这样写着:
<bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver">
<property name="defaultThemeName" value="dark" />
</bean>
当你点击页面上Light - Dark中的任意一个时,就发生了主题切换。这是怎么做到的呢?比如,你点击Light,这可是一个超链接啊!它链接到哪里去呢?人家只给了一个?,岂有此理!其实啊,默认是由themeChangeInterceptor这个家伙负责处理,也就说跳转到themeChangeInterceptor这里来了,为什么呢?你点击Light想干啥?切换主题啊!themeChangeInterceptor的天职就是为了切换而来的。让我们看看themeChangeInterceptor是如何处理的。
<mvc:interceptors>
<bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
<property name="paramName" value="theme"/>
</bean>
</mvc:interceptors>
你点击一个超链接意味着什么?意味着你发起了一次http请求。http请求会将你请求的参数theme=light保存到request中。themeChangeInterceptor接收到http请求,也就拿到了request。然后,上面mvc:interceptors…</mvc:interceptors>,之间有这么一段,也就是说,theme会被当作值赋给paramName,theme是键值对中的键啊!themeChangeInterceptor通过request拿到了theme=light,又通过paramName拿到了theme,那他接下来要干嘛?当然是获取键值对中的值light啊。拿到light后干嘛?当然是根据light获取style列表中的light.css,然后自然是交给themeResolver进行解析啊。themeResolver解析完成后,交给浏览器渲染。最后切换后的主题效果就呈选在你的眼前.