类图

ThemeResolver

接口 ThemeResolver 中定义的接口是比较简单的,提供两个接口:

  • resolveThemeName 获取样式名
  • setThemeName 设置样式名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface ThemeResolver {

/**
* 从请求中,解析出使用的主题。例如,从请求头 User-Agent ,判断使用 PC 端,还是移动端的主题
*
* Resolve the current theme name via the given request.
* Should return a default theme as fallback in any case.
* @param request request to be used for resolution
* @return the current theme name
*/
String resolveThemeName(HttpServletRequest request);

/**
* 设置请求,所使用的主题。
*
* Set the current theme name to the given one.
* @param request request to be used for theme name modification
* @param response response to be used for theme name modification
* @param themeName the new theme name ({@code null} or empty to reset it)
* @throws UnsupportedOperationException if the ThemeResolver implementation
* does not support dynamic changing of the theme
*/
void setThemeName(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName);

}

AbstractThemeResolver

抽象类 AbstractThemeResolver ,提供两个方法:

  • setDefaultThemeName 设置默认的样式名
  • getDefaultThemeName 获取默认的样式名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public abstract class AbstractThemeResolver implements ThemeResolver {

/**
* Out-of-the-box value for the default theme name: "theme".
*/
public static final String ORIGINAL_DEFAULT_THEME_NAME = "theme";

private String defaultThemeName = ORIGINAL_DEFAULT_THEME_NAME;

public void setDefaultThemeName(String defaultThemeName) {
this.defaultThemeName = defaultThemeName;
}

public String getDefaultThemeName() {
return this.defaultThemeName;
}

}

SessionThemeResolver

实现类 SessionThemeResolver 的实现也是比较简单的,就是将themeName 保存到 Session 中就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class SessionThemeResolver extends AbstractThemeResolver {

/**
* Name of the session attribute that holds the theme name.
* Only used internally by this implementation.
* Use {@code RequestContext(Utils).getTheme()}
* to retrieve the current theme in controllers or views.
* @see org.springframework.web.servlet.support.RequestContext#getTheme
* @see org.springframework.web.servlet.support.RequestContextUtils#getTheme
*/
public static final String THEME_SESSION_ATTRIBUTE_NAME = SessionThemeResolver.class.getName() + ".THEME";


@Override
public String resolveThemeName(HttpServletRequest request) {
String themeName = (String) WebUtils.getSessionAttribute(request, THEME_SESSION_ATTRIBUTE_NAME);
// A specific theme indicated, or do we need to fallback to the default?
return (themeName != null ? themeName : getDefaultThemeName());
}

@Override
public void setThemeName(
HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName) {
WebUtils.setSessionAttribute(request, THEME_SESSION_ATTRIBUTE_NAME,
(StringUtils.hasText(themeName) ? themeName : null));
}

}

FixedThemeResolver

没有具体操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class FixedThemeResolver extends AbstractThemeResolver {

@Override
public String resolveThemeName(HttpServletRequest request) {
return getDefaultThemeName();
}

@Override
public void setThemeName(
HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName) {
throw new UnsupportedOperationException("Cannot change theme - use a different theme resolution strategy");
}

}

CookieThemeResolver

将themeName 保存到 Cookie 中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
public class CookieThemeResolver extends CookieGenerator implements ThemeResolver {

/**
* The default theme name used if no alternative is provided.
*/
public static final String ORIGINAL_DEFAULT_THEME_NAME = "theme";

/**
* Name of the request attribute that holds the theme name. Only used
* for overriding a cookie value if the theme has been changed in the
* course of the current request! Use RequestContext.getTheme() to
* retrieve the current theme in controllers or views.
* @see org.springframework.web.servlet.support.RequestContext#getTheme
*/
public static final String THEME_REQUEST_ATTRIBUTE_NAME = CookieThemeResolver.class.getName() + ".THEME";

/**
* The default name of the cookie that holds the theme name.
*/
public static final String DEFAULT_COOKIE_NAME = CookieThemeResolver.class.getName() + ".THEME";


private String defaultThemeName = ORIGINAL_DEFAULT_THEME_NAME;


public CookieThemeResolver() {
setCookieName(DEFAULT_COOKIE_NAME);
}


/**
* Set the name of the default theme.
*/
public void setDefaultThemeName(String defaultThemeName) {
this.defaultThemeName = defaultThemeName;
}

/**
* Return the name of the default theme.
*/
public String getDefaultThemeName() {
return this.defaultThemeName;
}


@Override
public String resolveThemeName(HttpServletRequest request) {
// Check request for preparsed or preset theme.
String themeName = (String) request.getAttribute(THEME_REQUEST_ATTRIBUTE_NAME);
if (themeName != null) {
return themeName;
}

// Retrieve cookie value from request.
String cookieName = getCookieName();
if (cookieName != null) {
Cookie cookie = WebUtils.getCookie(request, cookieName);
if (cookie != null) {
String value = cookie.getValue();
if (StringUtils.hasText(value)) {
themeName = value;
}
}
}

// Fall back to default theme.
if (themeName == null) {
themeName = getDefaultThemeName();
}
request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, themeName);
return themeName;
}

@Override
public void setThemeName(
HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName) {

Assert.notNull(response, "HttpServletResponse is required for CookieThemeResolver");

if (StringUtils.hasText(themeName)) {
// Set request attribute and add cookie.
request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, themeName);
addCookie(response, themeName);
} else {
// Set request attribute to fallback theme and remove cookie.
request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, getDefaultThemeName());
removeCookie(response);
}
}

}