给webapp路径里的静态资源加时间戳[JS和CSS],Java自定义标签和Servlet的配置

来源:互联网 发布:pptv电视直播软件 编辑:程序博客网 时间:2024/05/09 04:36

        前几日做了一个很小的功能,一般工程启动后,为了能防止浏览器不缓存那些静态资源,比如js和css文件,一般的思路是在引用那些文件的路径后面增加一个时间戳,例如:

本来是下面这样的,

<link type="text/css" rel="stylesheet" href="/common.css">

但,这样的话如果用户不用ctrl+F5强制刷新页面的话可能会看不到最新的网页效果。所以为了解决这个小问题,我采用了很传统效率很低的一种方法[本人菜鸟]:

        1.  在项目启动的时候用servlet初始化的时候把webapp路径扫描一遍,然后存入一个map中,其中key存文件路径,value存时间戳,最后把这个map放入全局上下文ServletContext中。

        2.  自定义jsp标签,用于在jsp页面引用的时候替换上面的样式。

具体实现的办法如下:

       

<servlet>      <servlet-name>myServlet</servlet-name>      <servlet-class>com.myServlet</servlet-class>      <load-on-startup>0</load-on-startup></servlet><servlet-mapping>      <servlet-name>myServlet</servlet-name>      <url-pattern>/myPath</url-pattern></servlet-mapping>

以上是配置一个servlet,不解释了。

import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.log4j.Logger;public class myServlet extends HttpServlet {private static final long serialVersionUID = 1L;private static final Logger logger = Logger.getLogger(myServlet.class);private Map<String, String> map = new HashMap<String, String>();@Overridepublic void destroy() {super.destroy();}@Overridepublic void init() throws ServletException {logger.info(this.getClass().getName() + "静态资源装载开始......");ServletContext context = getServletContext();// 获得时间戳SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");String timestamp = "ver=" + sdf.format(new Date());String[] strPath = new String[] { "\\css", "\\edm", "\\gmw", "\\js","\\res", "\\script", "\\static", "\\styles", "\\themes" };String tempPath = ""; // 遍历strPath数组时用于存放临时的路径for (int i = 0; i < strPath.length; i++) {tempPath = strPath[i];String rootPath = context.getRealPath(tempPath);logger.info(this.getClass().getName() + "rootPath:" + rootPath);getPath(rootPath, timestamp, tempPath);}context.setAttribute("staticResource", map);logger.info(this.getClass().getName() + "静态资源装载完毕......");}/** *  * @param strPath *            项目绝对根路径 * @param time *            时间戳 * @param tempPath *            临时路径 */private void getPath(String strPath, String time, String tempPath) {String contextPath = getServletConfig().getServletContext().getContextPath();File dir = new File(strPath);File[] files = dir.listFiles();if (files == null) {return;} else {for (int i = 0; i < files.length; i++) {if (files[i].isDirectory()) {getPath(files[i].getAbsolutePath(), time, tempPath);} else {String strFileName = null;strFileName = files[i].getAbsolutePath();int loc = 0;if (strFileName.indexOf(tempPath) != -1 && (strFileName.endsWith("css") || strFileName.endsWith("js"))) {loc = strFileName.indexOf(tempPath);strFileName = strFileName.substring(loc);strFileName = strFileName.replaceAll("\\\\", "/");map.put(strFileName, contextPath + strFileName + "?"+ time);} else {continue;}}}}//循环输出静态资源路径,value为时间戳for (String path : map.keySet()) {System.out.println("path=" + path + " value=" + map.get(path));}}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {String contextPath = getServletConfig().getServletContext().getContextPath();// 获得时间戳SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");String timestamp = "ver=" + sdf.format(new Date());for (String path : map.keySet()) {map.put(path, contextPath + path + "?" + timestamp);}logger.info(this.getClass().getName() + "手动更新静态资源的时间戳完成......");resp.getWriter().write("update ok!");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {doGet(req, resp);}}

上面的代码是具体的遍历操作,都是基础,应该大家也都明白。需要注意的是doGet方法是用于手动更新时间戳的。

        我们继续

       

import javax.servlet.jsp.JspTagException;import javax.servlet.jsp.tagext.TagSupport;/** * JS 自定义标签,用于防止浏览器缓存 *  * @author  *  */public class JsTag extends TagSupport {private static final long serialVersionUID = 1L;private String jsSrc = "";// js路径public int doEndTaag() {return EVAL_PAGE;}public int doStartTag() throws JspTagException {try {String a = "<script type=\"text/javascript\" src=\"";String b = "\"></script>";pageContext.getOut().print(a + jsSrc + b);} catch (Exception e) {throw new JspTagException(e);}return SKIP_BODY;}public String getJsSrc() {return jsSrc;}public void setJsSrc(String jsSrc) {this.jsSrc = jsSrc;}}

以上功能是自定义了一个标签。

       

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"                        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"><taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>/p2p</short-name> <uri>tags</uri> <display-name>p2p</display-name> <description>     <![CDATA[Display P2P information.]]> </description>  <tag> <name>js</name> <tag-class>com.utils.JsTag</tag-class> <bodycontent>empty</bodycontent> <attribute>      <name>jsSrc</name>      <required>true</required>      <rtexprvalue>true</rtexprvalue>    </attribute> </tag>  <tag> <name>css</name> <tag-class>com.utils.cssTag</tag-class> <bodycontent>empty</bodycontent> <attribute>      <name>cssHref</name>      <required>true</required>      <rtexprvalue>true</rtexprvalue>    </attribute> </tag> </taglib>

上面的意思我还不太明白,等我懂了再过来更新,只知道这样配置,不好意思。

       

<jsp-config>    <!-- 自定义 tag --><taglib>   <taglib-uri>/tags</taglib-uri>   <taglib-location>/WEB-INF/tld/tag.tld</taglib-location></taglib></jsp-config>

上头这点东西在web.xml里加上即可。

上面这些就完成了一大半,剩下的工作就是在前台用了。

<script type="text/javascript" src="/res/js/index.js"></script>

原来是上面这种样子。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="js" uri="/tags"%><c:set var="staticResource" value="${staticResource}"/>

在jsp中配好自己需要的变量。

<js:js jsSrc="${staticResource['/res/js/index.js']}" />

用以上的代码替换原来的格式,就ok!
效果如下:

<script src="/res/js/index.js?ver=20131218143453" type="text/javascript">

千万别喷我,我第一次写博客,还是胡歌建议的呢~
下班了,如果有不明白的我有空再解释给大家,写的应该不是很明白,呵呵。

0 0