您的位置:首页 > 移动开发 > WebAPP

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

2013-12-19 18:58 609 查看
前几日做了一个很小的功能,一般工程启动后,为了能防止浏览器不缓存那些静态资源,比如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>();

@Override
public void destroy() {
super.destroy();
}

@Override
public 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));
}
}

@Override
protected 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!");
}

@Override
protected 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</tl
4000
ib-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">


千万别喷我,我第一次写博客,还是胡歌建议的呢~

下班了,如果有不明白的我有空再解释给大家,写的应该不是很明白,呵呵。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐