SpringMVC+FreeMarker實現靜態資源文件自動添加版本號(md5)


近日切換java開發,開始學習springframework。在實現靜態資源文件自動計算版本號的實例時,因為不熟悉框架,走了不少彎路,好在最終解決了問題。這里寫篇文章記錄一下實現,也希望對大家有些用處。

開發工具: eclipse,spring版本:5.0.1.RELEASE

  功能用途:為靜態資源文件計算版本號,可以避免客戶端緩存了靜態資源后,無法及時刷新服務器上最新版本文件的問題

 

  實現主要步驟說明:

 1、web.xml 配置springmvc的DispatcherServlet,攔截所有的請求(包括靜態資源請求);

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 <display-name>my springmvc</display-name>
 <servlet>
  <!-- 配置DispatcherServlet -->
  <servlet-name>springmvc</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <!-- 設置啟動順序 -->
  <!-- 指定spring mvc配置文件位置 不指定使用默認情況 -->
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <!-- <param-value>/WEB-INF/spring-mvc.xml,classpath*:/applicationContext.xml</param-value> -->
   <param-value>/WEB-INF/spring-mvc.xml,classpath*:application-*.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <!-- 配置映射 servlet-name和DispatcherServlet的servlet一致 -->
 <!-- 靜態資源要通過 DispatcherServlet 進行分發,這樣才能進行版本解析 -->
 <servlet-mapping>
  <servlet-name>springmvc</servlet-name>
  <!-- 攔截以/所有請求,服務端請求可以自己添加 .do 后綴即可 -->
  <url-pattern>/</url-pattern>
 </servlet-mapping>
</web-app>

 

 2、spring-mvc.xml 配置靜態資源的映射,以及MD5版本計算策略;

    <!--*:掃描所有的包,**:掃描所有的包&class-->
    <context:component-scan base-package="simm.spring.**" use-default-filters="true"/>
    <!--######## 靜態資源的請求以及地址映射 begin #######-->
    <mvc:resources mapping="/static/**" location="/static/"> <mvc:resource-chain resource-cache="true"> <mvc:resolvers> <mvc:version-resolver> <mvc:content-version-strategy patterns="/**"/> </mvc:version-resolver> </mvc:resolvers> </mvc:resource-chain> </mvc:resources>
    <!--######## 靜態資源的請求以及地址映射 end #######-->

 

 

 

3、實現一個@ControllerAdvice 控制器全局增強類,對所有的controller進行攔截,輸出ResourceUrlProvider 屬性到view層;

/** * 控制器的全局增強 * @author wh-simm * */ @ControllerAdvice public class ControllerConfig { @Autowired ResourceUrlProvider resourceUrlProvider; @ModelAttribute("urls") public ResourceUrlProvider urls() { return this.resourceUrlProvider; }

 

 4、FreeMarker 模板上通過調用ResourceUrlProvider.getForLookupPath(string url) 獲取帶有版本號的靜態資源;

resouceimp.ftl 宏方法定義

<#-- 靜態資源版本控制 --><#macro cssRef url>
    <link rel="stylesheet" type="text/css" href="${request.contextPath}${urls.getForLookupPath(url)}" />
</#macro>
<#macro jsRef url>
    <script type="text/javascript" src="${request.contextPath}${urls.getForLookupPath(url)}"></script>
</#macro>
<#-- 獲取請求地址 帶context -->
<#macro geturl url> ${request.contextPath}${url} </#macro>

 

_base.ftl 母版頁實現

<#macro layout>
<#include "/templates/resouceimp.ftl"/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xml:lang="zh-CN" xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title><#nested "title"/>-Spring-Boot</title>
<link rel="shortcut icon" type="image/ico" href="${request.contextPath!}/favicon.ico">
<!-- basic styles -->
<@cssRef url="/static/_resources/bootstrap/css/bootstrap.min.css"/>
<#nested "css" />
<@jsRef url="/static/_resources/jquery/jquery-2.0.3.min.js"/>
<@jsRef url="/static/_resources/common/utility.js"/>
</head>
<body class="easyui-layout layout panel-noscroll" style="background-color:white;">
    <#nested "content" />
    <input type="hidden" id="hid_contextpath" value="${request.contextPath!}"/>
    <input type="hidden" id="_mode" value="${formMode!}" />
</body>
</html>
<!-- ace scripts -->
<@jsRef url="/static/_resources/bootstrap/js/bootstrap.min.js"/>
<@jsRef url="/static/_resources/bootstrap/js/bootstrap-table.js"/>
<@jsRef url="/static/_resources/bootstrap/js/bootstrap-table-zh-CN.js"/>
<#nested "scripts"/>
</#macro>

 

 test.html 測試頁面

<#include "/templates/_base.ftl"/>
<@layout;section>
<#if section="title"> 測試界面 <#elseif section="css">
<#elseif section="content">
  <p>Greeting : ${greeting}</p>
  <p>Context : ${request.contextPath!}</p>
  <p>Author : ${author!}</p>
<#elseif section="scripts">
     <script type="text/javascript"> $(function () { alert("頁面初始化完成"); }); </script>
</#if>
</@layout>

 

5、請求結果展示

 

參考資料

http://blog.csdn.net/xichenguan/article/details/52794862

 http://blog.csdn.net/isea533/article/details/50412212

http://www.bubuko.com/infodetail-905264.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM