Elim的博客

用来记录一些原创性的总结


Elim

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来解析,它有三个实现:

它们三个都可以通过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所写)