国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring Boot一鍵換膚,so easy!

Spring Boot一鍵換膚,so easy!

2021-04-24 01:09江南一點雨 Java教程

Theme,就是主題,點一下就給網站更換一個主題,相信大家都用過類似功能,這個其實和前面所說的國際化功能很像,代碼其實也很像,今天我們就來捋一捋Spring Boot一鍵換膚功能的實現方法

Spring Boot一鍵換膚,so easy!

SpringMVC 源碼分析系列最后一篇,和大家聊一聊 Theme。

Theme,就是主題,點一下就給網站更換一個主題,相信大家都用過類似功能,這個其實和前面所說的國際化功能很像,代碼其實也很像,今天我們就來捋一捋。

考慮到有的小伙伴可能還沒用過 Theme,所以這里松哥先來說下用法,然后我們再進行源碼分析。

1.一鍵換膚

來做一個簡單的需求,假設我的頁面上有三個按鈕,點擊之后就能一鍵換膚,像下面這樣:

Spring Boot一鍵換膚,so easy!

我們來看下這個需求怎么實現。

首先三個按鈕分別對應了三個不同的樣式,我們先把這三個不同的樣式定義出來,分別如下:

blue.css:

  1. body{ 
  2.     background-color: #05e1ff; 

green.css:

  1. body{ 
  2.     background-color: #aaff9c; 

red.css:

  1. body{ 
  2.     background-color: #ff0721; 

主題的定義,往往是一組樣式,因此我們一般都是在一個 properties 文件中將同一主題的樣式配置在一起,這樣方便后期加載。

所以接下來我們在 resources 目錄下新建 theme 目錄,然后在 theme 目錄中創建三個文件,內容如下:

blue.properties:

  1. index.body=/css/blue.css 

green.properties:

  1. index.body=/css/green.css 

red.properties:

  1. index.body=/css/red.css 

在不同的 properties 配置文件中引入不同的樣式,但是樣式定義的 key 都是 index.body,這樣方便后期在頁面中引入。

接下來在 SpringMVC 容器中配置三個 Bean,如下:

  1. <mvc:interceptors> 
  2.     <mvc:interceptor> 
  3.         <mvc:mapping path="/**"/> 
  4.         <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"
  5.             <property name="paramName" value="theme"/> 
  6.         </bean> 
  7.     </mvc:interceptor> 
  8. </mvc:interceptors> 
  9. <bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource"
  10.     <property name="basenamePrefix" value="theme."/> 
  11. </bean> 
  12. <bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver"
  13.     <property name="defaultThemeName" value="blue"/> 
  14. </bean> 

 

 

 

 

 

首先配置攔截器 ThemeChangeInterceptor,這個攔截器用來解析主題參數,參數的 key 為 theme,例如請求地址是 /index?theme=blue,該攔截器就會自動設置系統主題為 blue。當然也可以不配置攔截器,如果不配置的話,就可以單獨提供一個修改主題的接口,然后手動修改主題,類似下面這樣:

  1. @Autowired 
  2. private ThemeResolver themeResolver; 
  3. @RequestMapping(path = "/01/{theme}",method = RequestMethod.GET) 
  4. public String theme1(@PathVariable("theme") String themeStr, HttpServletRequest request, HttpServletResponse response){ 
  5.     themeResolver.setThemeName(request,response, themeStr); 
  6.     return "redirect:/01"

themeStr 就是新的主題名稱,將其配置給 themeResolver 即可。

接下來配置 ResourceBundleThemeSource,這個 Bean 主要是為了加載主題文件,需要配置一個 basenamePrefix 屬性,如果我們的主題文件放在文件夾中,這個 basenamePrefix 的值就是 文件夾名稱.。

接下來配置主題解析器,主題解析器有三種,分別是 CookieThemeResolver、FixedThemeResolver、SessionThemeResolver,這里我們使用的是 SessionThemeResolver,主題信息將被保存在 Session 中,只要 Session 不變,主題就一直有效。這三個主題解析器松哥會在下一小節中和大家仔細分析。

配置完成后,我們再來提供一個測試頁面,如下:

  1. <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> 
  2. <%@ page contentType="text/html;charset=UTF-8" language="java" %> 
  3. <html> 
  4. <head> 
  5.     <title>Title</title> 
  6.     <link rel="stylesheet" href="<spring:theme code="index.body" />" > 
  7. </head> 
  8. <body> 
  9. <div> 
  10.     一鍵切換主題:<br/> 
  11.     <a href="/index?theme=blue">托帕藍</a> 
  12.     <a href="/index?theme=red">多巴胺紅</a> 
  13.     <a href="/index?theme=green">石竹青</a> 
  14. </div> 
  15. <br/> 
  16. </body> 
  17. </html> 

最關鍵的是:

  1. <link rel="stylesheet" href="<spring:theme code="index.body" />" > 

css 樣式不直接寫,而是引用我們在 properties 文件中定義的 index.body,這樣將根據當前主題加載不同的 css 文件。

最后再提供一個處理器,如下:

  1. @GetMapping(path = "/index"
  2. public  String getPage(){ 
  3.     return "index"

這個就很簡單了,沒啥好說的。

最后啟動項目進行測試,大家就可以看到我們文章一開始給出的圖片了,點擊不同的按鈕就可以實現背景的切換。

是不是非常 Easy!

2.原理分析

主題這塊涉及到的東西主要就是主題解析器,主題解析器和我們前面所說的國際化的解析器非常類似,但是比它更簡單,我們一起來分析下。

先來看下 ThemeResolver 接口:

  1. public interface ThemeResolver { 
  2.  String resolveThemeName(HttpServletRequest request); 
  3.  void setThemeName(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName); 

這個接口中就兩個方法:

  • resolveThemeName:從當前請求中解析出主題的名字。
  • setThemeName:設置當前主題。

ThemeResolver 主要有三個實現類,繼承關系如下:

Spring Boot一鍵換膚,so easy!

接下來我們對這幾個實現類來逐個分析。

2.1 CookieThemeResolver

直接上源碼吧:

  1. @Override 
  2. public String resolveThemeName(HttpServletRequest request) { 
  3.  String themeName = (String) request.getAttribute(THEME_REQUEST_ATTRIBUTE_NAME); 
  4.  if (themeName != null) { 
  5.   return themeName; 
  6.  } 
  7.  String cookieName = getCookieName(); 
  8.  if (cookieName != null) { 
  9.   Cookie cookie = WebUtils.getCookie(request, cookieName); 
  10.   if (cookie != null) { 
  11.    String value = cookie.getValue(); 
  12.    if (StringUtils.hasText(value)) { 
  13.     themeName = value; 
  14.    } 
  15.   } 
  16.  } 
  17.  if (themeName == null) { 
  18.   themeName = getDefaultThemeName(); 
  19.  } 
  20.  request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, themeName); 
  21.  return themeName; 
  22. @Override 
  23. public void setThemeName(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName) { 
  24.  if (StringUtils.hasText(themeName)) { 
  25.   request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, themeName); 
  26.   addCookie(response, themeName); 
  27.  } else { 
  28.   request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, getDefaultThemeName()); 
  29.   removeCookie(response); 
  30.  } 

先來看 resolveThemeName 方法:

  • 首先會嘗試直接從請求中獲取主題名稱,如果獲取到了,就直接返回。
  • 如果第一步沒有獲取到主題名稱,接下來就嘗試從 Cookie 中獲取主題名稱,Cookie 也是從當前請求中提取,利用 WebUtils 工具進行解析,如果解析到了主題名稱,就賦值給 themeName 變量。
  • 如果前面沒有獲取到主題名稱,就使用默認的主題名稱,開發者可以自行配置默認的主題名稱,如果不配置,就是 theme。
  • 將解析出來的 theme 保存到 request 中,以備后續使用。

再來看 setThemeName 方法:

  • 如果存在 themeName 就進行設置,同時將 themeName 添加到 Cookie 中。
  • 如果不存在 themeName,就設置一個默認的主題名,同時從 response 中移除 Cookie。

可以看到,整個實現思路還是非常簡單的。

2.2 AbstractThemeResolver

  1. public abstract class AbstractThemeResolver implements ThemeResolver { 
  2.  public static final String ORIGINAL_DEFAULT_THEME_NAME = "theme"
  3.  private String defaultThemeName = ORIGINAL_DEFAULT_THEME_NAME; 
  4.  public void setDefaultThemeName(String defaultThemeName) { 
  5.   this.defaultThemeName = defaultThemeName; 
  6.  } 
  7.  public String getDefaultThemeName() { 
  8.   return this.defaultThemeName; 
  9.  } 

AbstractThemeResolver 主要提供了配置默認主題的能力。

2.3 FixedThemeResolver

  1. public class FixedThemeResolver extends AbstractThemeResolver { 
  2.  
  3.  @Override 
  4.  public String resolveThemeName(HttpServletRequest request) { 
  5.   return getDefaultThemeName(); 
  6.  } 
  7.  
  8.  @Override 
  9.  public void setThemeName( 
  10.    HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName) { 
  11.  
  12.   throw new UnsupportedOperationException("Cannot change theme - use a different theme resolution strategy"); 
  13.  } 
  14.  

FixedThemeResolver 就是使用默認的主題名稱,并且不允許修改主題。

2.4 SessionThemeResolver

  1. public class SessionThemeResolver extends AbstractThemeResolver { 
  2.  public static final String THEME_SESSION_ATTRIBUTE_NAME = SessionThemeResolver.class.getName() + ".THEME"
  3.  @Override 
  4.  public String resolveThemeName(HttpServletRequest request) { 
  5.   String themeName = (String) WebUtils.getSessionAttribute(request, THEME_SESSION_ATTRIBUTE_NAME); 
  6.   return (themeName != null ? themeName : getDefaultThemeName()); 
  7.  } 
  8.  @Override 
  9.  public void setThemeName( 
  10.    HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName) { 
  11.   WebUtils.setSessionAttribute(request, THEME_SESSION_ATTRIBUTE_NAME, 
  12.     (StringUtils.hasText(themeName) ? themeName : null)); 
  13.  } 

resolveThemeName:從 session 中取出主題名稱并返回,如果 session 中的主題名稱為 null,就返回默認的主題名稱。

setThemeName:將主題配置到請求中。

不想多說,因為很簡單。

2.5 ThemeChangeInterceptor

最后我們再來看一看 ThemeChangeInterceptor 攔截器,這個攔截器會自動從請求中提取出主題參數,并設置到請求中,核心部分在 preHandle 方法中:

  1. @Override 
  2. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
  3.   throws ServletException { 
  4.  String newTheme = request.getParameter(this.paramName); 
  5.  if (newTheme != null) { 
  6.   ThemeResolver themeResolver = RequestContextUtils.getThemeResolver(request); 
  7.   if (themeResolver == null) { 
  8.    throw new IllegalStateException("No ThemeResolver found: not in a DispatcherServlet request?"); 
  9.   } 
  10.   themeResolver.setThemeName(request, response, newTheme); 
  11.  } 
  12.  return true

從請求中提取出 theme 參數,并設置到 themeResolver 中。

3.小結

好啦,這就是今天和小伙伴們分享的一鍵換膚!無論是功能性還是源碼,都和國際化非常類似,但是比國際化簡單很多,不知道小伙伴們有沒有 GET 到呢?

原文地址:https://mp.weixin.qq.com/s/epVIGcCAZdW3vS80XG_duQ

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产视频综合在线 | 国产日韩精品在线 | 午夜四虎 | 国产精品久久国产精品 | 一级黄色在线 | 在线观看91 | 国产精品九九九 | 亚洲精品一区二区三区四区高清 | 懂色av中文字幕一区二区三区 | а_天堂中文最新版地址 | 精品视频在线观看 | 国产日韩精品在线观看 | 天堂av资源 | 成人国产精品免费观看 | 亚洲免费在线播放 | 欧美精品成人一区二区三区四区 | 日韩1区| 国产成人精品一区二 | 免费在线黄色片 | 97久久久久久久久久久久 | 一区二区在线视频 | 欧美一级久久 | 欧美黄网站 | 黄色在线| 午夜在线小视频 | 午夜av影院 | 色狠狠久久av五月综合 | 久久影院免费观看 | 亚洲人成网站999久久久综合 | 久久精品国产99国产精品 | 免费一级片 | 免费毛片网站 | 国产一区二区三区在线免费观看 | 亚洲国产精品久久 | 欧美黄色成人 | 国产一区二区在线免费观看 | 夜夜福利 | 日韩影音| 在线黄色网 | 99精品国产一区二区三区 | 在线a视频 |