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

Filter和Interceptor的终归作用还是从入口修改或验证请求进来的数据的更多相关文章

  1. [转]web.xml中servlet ,filter ,listener ,interceptor的作用与区别

    原文链接:https://blog.csdn.net/netdevgirl/article/details/51483273 一.概念: 1.servlet:servlet是一种运行服务器端的java ...

  2. servlet/filter/listener/interceptor区别与联系

    转自:http://www.cnblogs.com/doit8791/p/4209442.html servlet.filter.listener是配置到web.xml中(web.xml 的加载顺序是 ...

  3. servlet & filter & listener & interceptor

    web.xml 的加载顺序是:context- param -> listener -> filter -> servlet * Servlet 对URL生效,用户处理用户的URL请 ...

  4. 过滤器和拦截器filter和Interceptor的区别

    1.创建一个Filter过滤器只需两个步骤 创建Filter处理类 web.xml文件中配置Filter 2.Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的 ...

  5. 【转】servlet/filter/listener/interceptor区别与联系

    原文:https://www.cnblogs.com/doit8791/p/4209442.html 一.概念: 1.servlet:servlet是一种运行服务器端的java应用程序,具有独立于平台 ...

  6. Java Web学习总结(29)——Java Web中的Filter和Interceptor比较

    1. 背景 在设计web应用的时候,用户登录/注册是必不可少的功能,对用户登录信息进行验证的方法也是多种多样,大致可以认为如下模式:前端验证+后台验证.根据笔者的经验,一般会在前端进行一些例如是否输入 ...

  7. Filter,Interceptor和Aspect

    过滤器使用的主要是反射 :拦截器使用的主要是回调 :AOP使用的主要是动态代理. 一个请求过来 ,先进行过滤器处理,看程序是否受理该请求.过滤器放过后, 程序中的拦截器进行处理,处理完后进入被AOP动 ...

  8. Spring 梳理 - filter、interceptor、aop实现与区别 -第二篇

    spring mvc中的Interceptor可以理解为是Spring MVC框架对AOP的一种实现方式.一般简单的功能又是通用的,每个请求都要去处理的,比如判断token是否失效可以使用spring ...

  9. spring boot 拦截 以及Filter和interceptor 、Aspect区别

    一.通过Filter这个大家很熟悉了吧,这是java规范的一个过滤器,他会拦截请求.在springboot中一般有两种配置方式.这种过滤器拦截并不知道你用的是哪一个Controller处理也不知道你用 ...

随机推荐

  1. (60)zabbix网络发现介绍Network Discovery

    网络发现简介 网络发现有什么用?网络发现怎么配置? 我们带着这两个问题开始我们的网络发现之旅. 比如小明有100台服务器,不想一台台主机去添加,能不能让zabbix自动添加主机呢,当然可以,网络发现便 ...

  2. Java测试技巧

    快捷键 修改快捷键 window->preference->general->keys: 查找引用:ctrl+shift+g 覆盖测试:alt+shift+E,T 复制一行:ctrl ...

  3. Vue—事件修饰符

    Vue事件修饰符 Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation(). Vue. ...

  4. PHP中文件锁与进程锁的使用区别

    php中文网的一篇文章,收为己用了.源地址: http://www.php.cn/php-weizijiaocheng-376853.html 本篇文章主要介绍了PHP 文件锁与进程锁的使用示例,小编 ...

  5. 菜鸟的《Linux程序设计》学习——MySQL数据库安装、配置及基本操作

    1. MySQL数据库: 在涉及到一些大型的Web系统或者嵌入式软件的开发时,都少不了用数据库来管理数据.在Windows操作系统下,使用过各种各样的数据库,如:sqlServer.Oracle.My ...

  6. Java中TreeMap集合讲解

    1.TreeSet介绍 TreeSet是一个有序集合,可以以任意顺序将元素插入到集合中,在对集合进行遍历的时候,每个元素将自动按照排序后的顺序呈现.底层使用的是二叉树(更具体点是红黑树)实现,对于元素 ...

  7. nginx+django+uwsgi+https 配置问题点

    - ssl 证书申请 申请域名的网站申请下载对应文件即可 - nginx  配置 https [root@VM_2_29_centos conf]# nginx -t nginx: [emerg] u ...

  8. 13-数组的API方法遍历

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  9. C/C++ 命令行参数的实现方法

    解析从命令行提供的参数可以使用 getopt函数. To use this facility, your program must include the header file unistd.h u ...

  10. HackerRank# Red John is Back

    原题地址 简单动归+素数判定,没用筛法也能过 代码: #include <cmath> #include <cstdio> #include <vector> #i ...