• Filter和Interceptor的终归作用还是从入口修改或验证请求进来的数据


    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对象,从而调用我们重写的方法实

  • 相关阅读:
    vi简单操作说明
    start django server
    计划
    在C#程序中使用ocx的方法
    在存储过程中使用另一个存储过程返回的查询结果集
    Java位操作大全(通用于C语言)
    对面象对象概念的理解、解释
    读书笔记 UltraGrid(14)
    Svcutil使用点滴
    水晶报表使用push模式(2)
  • 原文地址:https://www.cnblogs.com/panxuejun/p/7748066.html
Copyright © 2020-2023  润新知