博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java Web中的Filter和Interceptor的区别
阅读量:6865 次
发布时间:2019-06-26

本文共 3469 字,大约阅读时间需要 11 分钟。

hot3.png

1.问题的来源

项目中使用了Filter,进行白名单的控制,同时使用了Filter进行了跨域请求的控制,使用了Interceptor对用户请求的拦截,这两个到底啥区别呢?

Filter的使用,以下代码是从网上拷贝过来的,同时在web.xml进行配置:

public class requestFilter  implements Filter{    @Override    public void init(FilterConfig filterConfig) throws ServletException {            }    @Override    public void doFilter(ServletRequest request, ServletResponse resp, FilterChain chain)            throws IOException, ServletException {        HttpServletResponse response = (HttpServletResponse) resp;         response.setHeader("Access-Control-Allow-Origin", "*"); //解决跨域访问报错         response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");         response.setHeader("Access-Control-Max-Age", "3600"); //设置过期时间         response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type,         Accept, client_id, uuid, Authorization,token");         response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支持HTTP 1.1.         response.setHeader("Pragma", "no-cache"); // 支持HTTP 1.0.         response.setHeader("Expires", "0");         response.setContentType("application/json;charset=UTF-8");        response.setContentType("application/x-www-form-urlencoded;charset=UTF-8");        response.setContentType("text/html;charset=UTF-8");        chain.doFilter(request, response);     }    @Override    public void destroy() {            }

注意:response.setHeader("Access-Control-Allow-Origin", "*"); //解决跨域访问报错 ;这句话的有问题,如果在生产环境中,什么地址都是访问的,所以在生产环境中,我们一般是不会这样做的。

 

2、什么是Filter

Servlet作为Java Web的基础,它的一个比较核心也被广泛应用的功能就是Filter,又叫拦截器。顾名思义,拦截器就是起到拦截作用的。一般情况下,用户从客户端发出请求到服务器后,整个的流程是:

//HttpRequest --> Filter --> Servlet --> Controller/Action/... --> Filter --> HttpResponse

根据上面的流程可以看出,Filter的作用就是在用户请求到达Servlet之前,进行拦截。在拦截到用户的请求后,我们可以实现一些自定义的业务逻辑,例如白名单的设置,跨域的设置。Filter还可以在服务器响应到达客户端之前对响应的数据进行修改。

3、Filter的工作原理

Filter跟Servlet一样都是由服务器负责创建和销毁的,在web应用程序启动时,服务器会根据应用程序的web.xml文件中的配置信息调用public void init(FilterConfig filterConfig) throws ServletException方法来初始化Filter,在web应用程序被移除或者是服务器关闭时,会调用public void destroy()来销毁Filter。在一个应用程序中一个Filter只会被创建和销毁一次,在进行完初始化之后,Filter中声明了public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException方法,用来实现一些需要在拦截完成之后的业务逻辑。

注意:上面的doFilter()方法的参数中,有chain这个参数,它是传递过来的拦截链对象,里面包含了用户定义的一系列的拦截器,这些拦截器根据其在web.xml中定义的顺序依次被执行。当用户的信息验证通过或者当前拦截器不起作用时,我们可以执行chain.doFilter()方法来跳过当前拦截器来执行拦截器链中的下一个拦截器。同时,web.xml中<init-param>标签被用来配置Filter的初始化时使用的参数,其中<param-name>标签表示参数的名字,可以是自己定义的任何名字,<param-value>标签表示对应的初始化参数的值。上面的初始化参数中,redirectPath定义了当验证不成功时页面重定向的的路径,logonString定义了拦截器拦截的指定URL。<filter-mapping>标签定义了拦截器的拦截模式,在<url-pattern>标签定义了拦截模式,上面的/*表示拦截所有。它和之前定义的指定拦截的URL标签结合起来使用。

4.Interceptor

之前提到的Filter是Servlet层面的拦截器,在许多的Java Web框架中,都实现了自己的拦截器Interceptor。例如Struts2中的Interceptor、Spring MVC中的HandlerInterceptor等。相比于Filter,框架中的Interceptor的产生作用的时间和位置不一样,下面描述了应用了Spring MVC中的HandlerInterceptor的web请求流程:

HttpRequest ----> DispactherServlet ----> HandlerInterceptor ---->Controller----> HandlerInterceptor ----> HttpResponse

两者的主要区别在于Filter起作用的时机是在请求到达Servlet之前,二HandlerInterceptor其作用的时机是在DispactherServlet接收到用户请求完成请求到相应的Handler映射之后。虽然都先于在具体的业务逻辑执行,但是还是存在一些差异。Filter面对的是所有的请求,而HandlerInterceptor是面对具体的Controller。Filter总是先于HandlerInterceptor发挥作用,在Filter中甚至可以中断请求,从而使它无法到达相应的Servlet。而且两者的配置也不一样,Filter是在web.xml中进行配置,HandlerInterceptor是在具体的applicationContext.xml中进行配置。DispactherServlet是实现了Servlet接口的。

转载于:https://my.oschina.net/u/2380961/blog/1593919

你可能感兴趣的文章
haproxy实现均衡负载(linux)
查看>>
[Unity 3D]摄像机Clear Flags和Culling Mask属性用途详解
查看>>
实战阿里云-实战Fail2Ban之v0.9.3
查看>>
Net设计模式实例之单例模式( Singleton Pattern)(2
查看>>
RedHat9上oracle9.2的安装
查看>>
看黄仁勋的不跟随style NVIDIA在CES2018上继续说自动驾驶那些事儿
查看>>
samba报错:session setup failed: NT_STATUS_LOGON_FAILURE 解决
查看>>
快乐识记CSDN一些信息
查看>>
Java后端工程师学习大纲
查看>>
Android6.0动态获取权限
查看>>
Spring 中的 classpath*: 与 classpath: 通配符
查看>>
CCNP-35 BGP 5
查看>>
XML file
查看>>
快速构建datatable
查看>>
Android使用DownloadManager实现文件下载
查看>>
oracle编译存储过程提示表或视图不存在的问题分析
查看>>
基于OpenCV实现的Android移动端口红AR
查看>>
提升 IE7 的访问速度
查看>>
积少成多Flash(5) - ActionScript 3.0 实例之闹钟(自定义事件, 画图, 动画)
查看>>
GitHub 版本控制 项目托管 05 创建GitHub本地仓库1-创建空仓库
查看>>