Filter是Java EE标准。Inteceptor是Spring 标准。

Filter在servlet前面,Interveptor在servlet之后

Filter和Inteceptor都可以改变httpservlet里面的数据内容,实现可以不用在Controoler层再去做验证的步骤,很美妙。

比如,去1除空白http参数的空白字符,2权限检验过滤,3设置http进出内容的编码格式,4对加解密参数进行加解密

5登陆状态验证。

Httpservlet 里面加入数据时候,是request.put(k,V)形式。所以可以猜想出来,request里面封装了hashmap接口,才能实现put key value。装饰者模式

但有个最扫兴的地方,Filter和Inteceptor的传入参数httpseretquest,已经被设置成不可修改里面的对象了,所以你只能读取httpservletreuest的内容,但不能修改httpservletrequest内容。这个是最悲催的一点,不过也可以理解,Java ee和spring想的就是传到业务层的数据是原始的真实的数据,不允许进行内容修改。

要想修改herpservletrequest入参对象,就要使用httpservletrequestwrapper类

javax.servlet.http.HttpServletRequestWrapper类来装饰HttpServletRequest对象。

httpservletrequest是java ee标准,

httpservletrequestwrapper也是java ee标准

修改httpservletrequest不可变对象最关键的精髓在于,通过hrttttpservletrequestwrapper来重写httpservletrequest的方法,对重写,也就是覆盖,修改其方法的返回值。这样就变相修改了啊httpservletrequest的修改,其实httpservletrequest

依然没被修改,也不能修改,我们只是生成了wrapper类样,这个类封装进httpservletrequest对象了

例如,Struts通过调用HttpServletRequest对象的getParameterValues()对象来处理action表单。通过覆盖装饰类中此方法,你可以改变当前HttpServletRequest对象的状态。

程序代码: 
package trimmer.filter;

import java.io.IOException; 
import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest;

public class MyFilter implements Filter { 
private FilterConfig filterConfig;

public void init(FilterConfig filterConfig) throws ServletException { 
System.out.println("Filter initialized"); 
this.filterConfig = filterConfig; 
}

public void destroy() { 
System.out.println("Filter destroyed"); 
this.filterConfig = null; 
}

public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException { 
chain.doFilter(new MyRequestWrapper((HttpServletRequest) request), 
response); 

}

小结 
Servlet  filter可以在调用一个servlet的服务方法后,拦载或加工HTTP请求。尽管这非常诱人,但其实际使用却有所限制,因为你不能改变HttpServletRequest对象。 
这时候装饰模式派上了用场。本文演示了如何通过应用装饰模式来“修改”HttpServletRequest对象,从而使你的servlet  filter更加有用。在上面filter例子中,filter改了request参数中的用户输入,而这一点,如果没有装饰request对象,你是无论如何也不可能做到的。

----------------------------------------------------- 
package wrapper;   
  
import java.io.UnsupportedEncodingException;   
import java.net.URLDecoder;   
  
import javax.servlet.http.HttpServletRequest;   
import javax.servlet.http.HttpServletRequestWrapper;   
  
public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {   
  
    private String charset = "UTF-8";   
  
    public GetHttpServletRequestWrapper(HttpServletRequest request) {   
        super(request);   
    }   
  
    /**  
     * 获得被装饰对象的引用和采用的字符编码  
     * @param request  
     * @param charset  
     */  
    public GetHttpServletRequestWrapper(HttpServletRequest request,   
            String charset) {   
        super(request);   
        this.charset = charset;   
    }   
  
    /**  
     * 实际上就是调用被包装的请求对象的getParameter方法获得参数,然后再进行编码转换  
     */  
    public String getParameter(String name) {   
        String value = super.getParameter(name);   
        value = value == null ? null : convert(value);   
        return value;   
    }   
  
    public String convert(String target) {   
        System.out.println("编码转换之前:" + target);   
        try {   
            return new String(target.trim().getBytes("ISO-8859-1"), charset);   
        } catch (UnsupportedEncodingException e) {   
            return target;   
        }   
    }   
  

------------ 
public void doFilter(ServletRequest request, ServletResponse response,   
            FilterChain chain) throws IOException, ServletException {   
        //设置请求响应字符编码   
        request.setCharacterEncoding(charset);   
        response.setCharacterEncoding(charset);   
        //新增加的代码           
        HttpServletRequest req = (HttpServletRequest)request;   
           
        if(req.getMethod().equalsIgnoreCase("get"))   
        {   
            req = new GetHttpServletRequestWrapper(req,charset);   
        }   
           
        System.out.println("----请求被"+config.getFilterName()+"过滤");   
        //传递给目标servlet或jsp的实际上时包装器对象的引用,而不是原始的HttpServletRequest对象   
        chain.doFilter(req, response);   
           
        System.out.println("----响应被"+config.getFilterName()+"过滤");

2、继承HttpServletRequestWrapper 和HttpServletResponse 两个类对 getParameter(String str) 和getWrite()两方法进行重写,而方法中实现我们想要的操作

3、使用Filter过滤器,我们知道Filter是在请求到达servlet之前和servlet响应信息到达浏览器之前进行两次拦截,而就在到达server之前我们将FilterChain的doFilter(request,reponse)方法的request参数替换为我们装饰后的request而我们又重写的getParameter(String str)方法,之后调用的就是这个方法,因此也就完成了

请求参数的过滤和修改

4、响应和请求其实是一样的,也是替换了Response对象,从而调用我们重写的方法实

最新文章

  1. wpf 列表、菜单 收起与展开,通过Grid DoubleAnimation或者Expander实现
  2. iOS完整学习路线图
  3. php实现转换html格式为文本格式的方法
  4. Oracle to_char 转换数值
  5. mybatis if判断中的特殊符号
  6. Mysql如何清空数据库的所有表数据
  7. UVa1401 Remember the Word(DP+Trie树)
  8. poj1141 区间dp+路径
  9. template和templateUrl区别与联系
  10. Uncaught TypeError: Cannot read property 'call' of undefined jquery.validate.min.js:28
  11. ECMAScript6标准新增加的内容
  12. PAT (Advanced Level) 1101. Quick Sort (25)
  13. unset与unlink
  14. C#相等性 - “==”
  15. Python自然语言处理笔记【一】文本分类之监督式分类
  16. Linux下启动Oracle服务和监听程序
  17. MySQL Study之--MySQL普通用户无法本地登陆
  18. Digitalocean+DNSPod搭建Meteor.js博客Telescope.js
  19. 细说Cookie(转)
  20. poj 3070 Fibonacci 矩阵相乘

热门文章

  1. C语言数据类型_02
  2. node爬虫(简版)
  3. Ubuntu创建应用快捷方式
  4. luogu P1966 火柴排队 (逆序对)
  5. python mysql备份脚本
  6. LIN总线协议
  7. android 之 service
  8. 用python计算100以内的素数
  9. Centos 6.5升级openssh到7.5p1版本
  10. x86 保护方式 简介 一