SpringMVC对theme选择的支持
theme选择
一组主题通常是一组CSS和图片的组合,比如网址导航网站常见的以颜色区分的主题。SpringMVC提供了对主题的支持,由org.springframework.ui.context.Theme
表示。Theme由ThemeResource来根据theme名称来解析出来,它的定义如下。
public interface ThemeSource {
Theme getTheme(String themeName);
}
Spring提供的实现是ResourceBundleThemeSource,它是基于java.util.ResourceBundle
实现的,在使用时我们需要可以通过basenamePrefix指定一个前缀,当没有指定前缀时将从类的根路径下来获取主题文件。指定了前缀后就将从类路径下的指定路径下寻找,比如前缀为a/b
则将从类路径下的a/b
路径下寻找指定的主题文件。ResourceBundleThemeSource解析的主题文件需要是properties文件。当需要解析主题时Spring将从bean容器中寻找id为themeSource的ThemeSource。以下就是一个ResourceBundleThemeSource的定义。
<bean id="themeSource"
class="org.springframework.ui.context.support.ResourceBundleThemeSource"
p:basenamePrefix="META-INF/theme/" />
ThemeSource解析Theme时的主题名称将由ThemeResolver来解析,它有三个实现:
- FixedThemeResolver: 指定固定的主题名称。
- SessionThemeResolver:从Session中解析主题名称。
- CookieThemeResolver:从Cookie中解析主题名称。
它们三个都可以通过setDefaultThemeName指定默认的theme名称。即当从Session或Cookie中没能获取到主题名称时都将使用setDefaultThemeName指定的默认的主题名称。当没有通过setDefaultThemeName指定默认的主题名称时,默认的主题名称是theme。以下就是定义的一个基于Session的ThemeResolver。有需要时也可以实现自定义的。
<!-- 默认不指定默认的theme名称时,默认的theme名称是theme -->
<bean id="themeResolver"
class="org.springframework.web.servlet.theme.SessionThemeResolver"
p:defaultThemeName="default" />
定义好ThemeSource和ThemeResolver之后我们就可以来应用Theme了。首先我们需要在jsp页面上引入spring的taglib。
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
然后就可以通过<spring:theme code='style'/>
的形式来引用当前theme定义中的stylezhegekey对应的资源了。它的用法和作用与国际化的<spring:message code=""/>
是类似的。比如下面示例中的<link rel="stylesheet" type="text/css" href="<spring:theme code='style'/>">
就会寻找当前theme中的style这个key对应的资源并把它作为一个css文件的路径进行引入。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="<spring:theme code='style'/>">
<title>Test Theme Function</title>
</head>
<body>
<div style="width: 200px;height: 150px; margin-top: 100px; margin-left: 100px; border-width: 1px; border-style: solid;">
Test Theme;
</div>
</body>
</html>
此时,如果没有指定theme,按照我们上面的配置默认就会取名称为default
的theme,此时将到类路径的META-INF/theme
路径下寻找default.properties文件。如果default.properties文件的内容如下,则此时key为style的值对应的是/static/style/theme/default.css
,则此时<link rel="stylesheet" type="text/css" href="<spring:theme code='style'/>">
对应的就是<link rel="stylesheet" type="text/css" href="/static/style/theme/default.css">
。
style=/static/style/theme/default.css
如果解析出来的theme的名称是green
,则将从类路径下的META-INF/theme
路径下寻找green.properties文件中key为style的值。
需要注意的是每个theme中对应的key应该都是相同的,如果在当前theme中寻找某个不存在的key时,将直接抛出异常,而不会到默认的theme对应的文件中寻找。这是它跟国际化不同的地方。
切换theme
如果需要响应theme的切换,需要在拦截器中定义一个ThemeChangeInterceptor,这是SpringMVC内置的一个interceptor。定义了该interceptor之后就可以通过在URL上传递一个名为theme的参数用以指定当前需要使用的theme,具体需要拦截哪个URL以响应theme的切换则完全可以由你来决定,笔者下面这样的就是拦截所有的URL。如果不想使用默认的参数,则可以通过ThemeChangeInterceptor的setParamName()方法用来指定。使用默认的切换参数时就可以通过http://localhost/xxx?theme=green
来切换当前的theme为green。
<mvc:interceptors>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" />
</mvc:interceptors>
(注:本文是基于Spring4.1.0所写)