1.问题的来源html
项目中使用了Filter,进行白名单的控制,同时使用了Filter进行了跨域请求的控制,使用了Interceptor对用户请求的拦截,这两个到底啥区别呢?java
Filter的使用,如下代码是从网上拷贝过来的,同时在web.xml进行配置:web
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", "*"); //解决跨域访问报错 ;这句话的有问题,若是在生产环境中,什么地址都是访问的,因此在生产环境中,咱们通常是不会这样作的。json
二、什么是Filter跨域
Servlet做为Java Web的基础,它的一个比较核心也被普遍应用的功能就是Filter,又叫拦截器。顾名思义,拦截器就是起到拦截做用的。通常状况下,用户从客户端发出请求到服务器后,整个的流程是:服务器
//HttpRequest --> Filter --> Servlet --> Controller/Action/... --> Filter --> HttpResponse
根据上面的流程能够看出,Filter的做用就是在用户请求到达Servlet以前,进行拦截。在拦截到用户的请求后,咱们能够实现一些自定义的业务逻辑,例如白名单的设置,跨域的设置。Filter还能够在服务器响应到达客户端以前对响应的数据进行修改。app
三、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标签结合起来使用。ide
4.Interceptorui
以前提到的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接口的。