缓存Filter(一步一步学习J2EE)

本文详细介绍了缓存Filter在J2EE中的工作流程,包括拦截GET请求、检查缓存、处理POST请求等情况。同时,强调了使用缓存Filter的注意事项,如不适用于实时数据和POST提交,以及依赖Cookie而非Session。通过《java Web整合开发...》一书,实现了一个简单的缓存Filter,该Filter重写了HttpServletResponseWrapper的相关方法。

缓存Filter工作流程:

1)截获浏览器提交的request

2)如果请求方式为"POST"则不经过缓存

3)若请求方式为"GET"且存在缓存且缓存没有过期,返回缓存数据

4)若不存在缓存或缓存已过期,则查询并创建缓存;返回数据

使用缓存Filter注意事项

1)缓存Filter不用于实时变化数据。适用于数据变化不大但访问次数多的内容:如论坛、博客、新闻等

2)缓存Filter不用于"POST"方式提交数据,如登陆、发表文章等

3)缓存内容要依赖于Cookie而不能依赖于Session,即用Cookie而不是Session纪录客户身份。且无论客户身份是管理员还是普通浏览着 Servlet 输出数据都相同,只能在浏览器层使用JavaScript根据Cookie来决定显示什么内容。


参照《java Web整合开发...》实现一个简单的缓存Filter主要完成以下工作

1)继承 HttpServletResponseWrapper  ,重写必要方法

package servlet.filter;

import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class CacheResponseWrapper extends HttpServletResponseWrapper {

	
	/*可用作 Writer 的字符缓冲区。当数据写入流时,缓冲区自动扩大*/
	private CharArrayWriter cacheWriter = new CharArrayWriter();
		
	public CacheResponseWrapper(HttpServletResponse response) {
		super(response);
	}

	@Override
	public void flushBuffer() throws IOException {
		cacheWriter.flush();
	}

	@Override
	public PrintWriter getWriter() throws IOException {
		return new PrintWriter(cacheWriter);//返回缓存内容的Writer;
	}

	public void finishResponse(){
		cacheWriter.close();
	}
	
	/*Getters and Setters*/
	public CharArrayWriter getCacheWriter() {
		return cacheWriter;
	}

	public void setCacheWriter(CharArrayWriter cacheWriter) {
		this.cacheWriter = cacheWriter;
	}
	
}

2)Filte接口

package servlet.filter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.URLEncoder;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CacheFilter implements Filter{
	
	/**/
	private ServletContext context;
	/**/
	private File tempDir;
	
	private long cacheTime = Long.MAX_VALUE;
	
	/*撤销*/
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req=(HttpServletRequest) request;
		HttpServletResponse rep=(HttpServletResponse) response;
		
		/*请求方式为POST则不经过缓存*/
		if("POST".equalsIgnoreCase(req.getMethod())){
			chain.doFilter(req, rep);
		}
		
		String uri=req.getRequestURI();
		if(uri==null){
			uri="";
		}
		/*替换特殊字符*/
		uri=uri.replace(req.getContextPath()+"/", "");
		uri=uri.trim().length()==0 ? "index.jsp" : "";
		uri=req.getQueryString()==null ? uri : uri+req.getQueryString();
		/*缓存文件*/
		File cacheFile=new File(tempDir,URLEncoder.encode(uri,"UTF-8") );
		
		/*缓存文件不存在或已过期,则请求Servlet并缓存数据*/
		if( !cacheFile.exists()
			|| ( cacheFile.length()==0 )
			|| ( System.currentTimeMillis()-cacheFile.lastModified() )>cacheTime ){
			/*使用自定义response 缓存输出内容*/
			CacheResponseWrapper crep = new CacheResponseWrapper(rep);
			
			chain.doFilter(req, crep);
			/*创建缓存文件*/
			tempDir.mkdir();
			cacheFile.createNewFile();
			/*输出内容到缓存文件*/
			char[] content=crep.getCacheWriter().toCharArray();
			Writer writer=new OutputStreamWriter( new FileOutputStream(cacheFile));
			writer.write(content);
			writer.flush();
			writer.close();
		}
		
		String contenType=context.getMimeType(req.getRequestURI());
		rep.setContentType(contenType);
		
		/*读取缓存文件内容,输出到浏览器*/
		Reader ins = new InputStreamReader( new FileInputStream(cacheFile),"UTF-8" );
		int len;
		char[] cbuf=new char[1024];
		StringBuilder sb=new StringBuilder();
		while( (len=ins.read(cbuf) )>-1 ){
			sb.append(cbuf, 0, len);
		}
		ins.close();
		
		rep.getWriter().write(sb.toString());
	}
	
	/*初始化*/
	public void init(FilterConfig config) throws ServletException {
		context=config.getServletContext();
		/*从配置文件获取*/
		tempDir=new File(config.getInitParameter("cacheDir"));
		/*从配置文件获取缓存时间*/
		cacheTime=Long.parseLong(config.getInitParameter("cacheTime"));
	}
	
}

3)配置


	<filter>
		<filter-name>cacheFilter</filter-name>
		<filter-class>servlet.filter.CacheFilter</filter-class>
		<init-param>
		<param-name>cacheDir</param-name>
		<param-value>cache</param-value>
		</init-param>
		<init-param>
		<param-name>cacheTime</param-name>
		<param-value>100000</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>cacheFilter</filter-name>
		<url-pattern>*</url-pattern>
	</filter-mapping>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值