Filter过滤器高级应用

Filter过滤器高级应用

  • 由于开发人员在filter中可以得到代表用户请求和响应 的request、response对象,因此在编程中可以使用 Decorator(装饰器)模式对request、response对象进行 包装,再把包装对象传给目标资源,从而实现一些特 殊需求。

  • 增强模式

    • 当某个对象的方法不适应业务需求时,通常有2种方式可以对方法进行增强:
      • 编写子类,覆盖需增强的方法
      • 使用Decorator设计模式对方法进行增强
  • Decorator设计模式的实现

  1. 首先看需要被增强对象继承了什么接口或父类,编写一个 类也去继承这些接口或父类。
  2. 在类中定义一个变量,变量类型即需增强对象的类型。
  3. 在类中定义一个构造函数,接收需增强的对象。
  4. 覆盖需增强的方法,编写增强的代码
  • Servlet API 中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper ,(HttpServletRequestWrapper类实现了request接口中的所有方法,但这些方法的内部实现都是仅仅调用了一下所包装的的request对象的对应方法)以避免用户在对request对象进行增强时需要实现request接口中的所有方法
  • 案例一:解决乱码
//为解决全站乱码
public class CharacterEncodingFilter implements Filter {

	public void destroy() {
		// TODO Auto-generated method stub

	}

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		
		request.setCharacterEncoding("gb2312");
		response.setCharacterEncoding("gb2312");
		response.setContentType("text/html;charset=gb2312");
		
		
		MyCharacterEncodingRequest requestWrapper = new MyCharacterEncodingRequest(request);
		chain.doFilter(requestWrapper, response);
		

	}

	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub

	}
}

/*
1.实现与被增强对象相同的接口 
2、定义一个变量记住被增强对象
3、定义一个构造器,接收被增强对象
4、覆盖需要增强的方法
5、对于不想增强的方法,直接调用被增强对象(目标对象)的方法
 */
 
class MyCharacterEncodingRequest extends HttpServletRequestWrapper{
	
	private HttpServletRequest request;
	public MyCharacterEncodingRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	@Override
	public String getParameter(String name) {
		
		try{
			String value= this.request.getParameter(name);
			if(value==null){
				return null;
			}
			
			if(!this.request.getMethod().equalsIgnoreCase("get")) {
				return value;
			}
			
			value = new String(value.getBytes("ISO8859-1"),this.request.getCharacterEncoding());
			return value;
			
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
  • 案例2:压缩响应
//解决全站压缩
public class GzipFilter implements Filter {

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		
		BufferResponse myresponse = new BufferResponse(response);
		
		chain.doFilter(request, myresponse);
		
		
		//拿出缓存中的数据,压缩后再打给浏览器
		byte out[] = myresponse.getBuffer();
		System.out.println("原始大小:" + out.length);
		
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		GZIPOutputStream gout = new GZIPOutputStream(bout);
		gout.write(out);
		gout.close();
		
		
		byte gzip[] = bout.toByteArray();
		System.out.println("压缩后的大小:" + gzip.length);
		
		
		response.setHeader("content-encoding", "gzip");
		response.setContentLength(gzip.length);
		response.getOutputStream().write(gzip);
	}
	
	public void destroy() {
	}

	public void init(FilterConfig filterConfig) throws ServletException {
	}
}

class BufferResponse extends HttpServletResponseWrapper{

	private ByteArrayOutputStream bout = new ByteArrayOutputStream();
	
	private PrintWriter pw;
	private HttpServletResponse response;
	public BufferResponse(HttpServletResponse response) {
		super(response);
		this.response = response;
	}
	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		return new MyServletOutputStream(bout);
	}
	@Override
	public PrintWriter getWriter() throws IOException {
		pw = new PrintWriter(new OutputStreamWriter(bout,this.response.getCharacterEncoding()));  //PrintWriter.write(中国) <br>
		return pw;
	}
	
	public byte[] getBuffer(){
		try{
			if(pw!=null){
				pw.close();
			}
			if(bout!=null){
				bout.flush();
				return bout.toByteArray();
			}
			
			
			return null;
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

class MyServletOutputStream extends ServletOutputStream{

	private ByteArrayOutputStream bout;
	public MyServletOutputStream(ByteArrayOutputStream bout){
		this.bout = bout;
	}
	
	@Override
	public void write(int b) throws IOException {
		this.bout.write(b);
	}
}
  • 案例3:缓存数据到内存
//缓存数据到内存
public class CachedFilter implements Filter {

	private Map<String,byte[]> map = new HashMap<String,byte[]>();
	

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		
		//1.得到用户请求的uri
		String uri = request.getRequestURI();
		
		//2.看缓存中有没有uri对应的数据
		byte b[] = map.get(uri);
		
		//3.如果缓存中有,直接拿缓存的数据打给浏览器,程序返回
		if(b!=null){
			response.getOutputStream().write(b);
			return;
		}
		
		//4.如果缓存没有,让目标资源执行,并捕获目标资源的输出
		BufferResponse1 myresponse = new BufferResponse1(response);
		chain.doFilter(request, myresponse);
		byte out[] = myresponse.getBuffer();
		
		//5.把资源的数据以用户请求的uri为关键字保存到缓存中
		map.put(uri, out);
		
		//6.把数据打给浏览器
		response.getOutputStream().write(out);
	}

	public void init(FilterConfig filterConfig) throws ServletException {
	}
	
	public void destroy() {
	}
}

class BufferResponse1 extends HttpServletResponseWrapper{

	private ByteArrayOutputStream bout = new ByteArrayOutputStream();  //捕获输出的缓存
	
	private PrintWriter pw;
	
	private HttpServletResponse response;
	public BufferResponse1(HttpServletResponse response) {
		super(response);
		this.response = response;
	}
	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		
		return new MyServletOutputStream1(bout);
	}
	@Override
	public PrintWriter getWriter() throws IOException {
		pw = new PrintWriter(new OutputStreamWriter(bout,this.response.getCharacterEncoding()));
		return pw;
	}
	
	public byte[] getBuffer(){
		try{
			if(pw!=null){
				pw.close();
			}
			return bout.toByteArray();
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

class MyServletOutputStream1 extends ServletOutputStream{

	private ByteArrayOutputStream bout;
	public MyServletOutputStream1(ByteArrayOutputStream bout){  //接收数据写到哪里
		this.bout = bout;
	}
	
	@Override
	public void write(int b) throws IOException {
		bout.write(b);
	}
	
}
  • 案例4:敏感词过滤
//脏话过滤器
public class DirtyFilter implements Filter {
	
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {

		
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		DirtyRequest dirtyrequest = new DirtyRequest(request);
		
		chain.doFilter(dirtyrequest, response);
	}

	public void init(FilterConfig filterConfig) throws ServletException {
	}
	
	public void destroy() {
	}
}

class DirtyRequest extends HttpServletRequestWrapper{

	private List<String> dirtyWords = Arrays.asList("傻B","操蛋","畜生");
	private HttpServletRequest request;
	public DirtyRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	@Override
	public String getParameter(String name) {
		
		String value = this.request.getParameter(name);
		if(value==null){
			return null;
		}
		
		for(String dirtyWord : dirtyWords){
			if(value.contains(dirtyWord)){
				value = value.replace(dirtyWord, "****");
			}
		}
		return value;
	}
}
  • 案例5:html转义
//html转义过滤器
public class HtmlFilter implements Filter {

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		
		
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;

		MyHtmlRequest myrequest = new MyHtmlRequest(request);
		chain.doFilter(myrequest, response);
		
	}

	
	public void destroy() {
		// TODO Auto-generated method stub

	}

	
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub

	}
}

class MyHtmlRequest extends HttpServletRequestWrapper{

	private HttpServletRequest request;
	
	public MyHtmlRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}

	@Override
	public String getParameter(String name) {
		
		String value = this.request.getParameter(name);
		if(value==null){
			return null;
		}
		return filter(value);
	}
	
	 public String filter(String message) {

	        if (message == null)
	            return (null);

	        char content[] = new char[message.length()];
	        message.getChars(0, message.length(), content, 0);
	        StringBuffer result = new StringBuffer(content.length + 50);
	        for (int i = 0; i < content.length; i++) {
	            switch (content[i]) {
	            case '<':
	                result.append("&lt;");
	                break;
	            case '>':
	                result.append("&gt;");
	                break;
	            case '&':
	                result.append("&amp;");
	                break;
	            case '"':
	                result.append("&quot;");
	                break;
	            default:
	                result.append(content[i]);
	            }
	        }
	        return (result.toString());

	    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值