过滤器和拦截器以及在springboot中的使用

  1. 云栖社区>
  2. 博客>
  3. 正文

过滤器和拦截器以及在springboot中的使用

坎布里奇 2019-07-01 01:05:07 浏览334
展开阅读全文

一拦截器

一、拦截器(Interceptor)

  定义:在面向切面编程中应用的,在方法执行之前或者之后,进行拦截,添加某些操作;基于java的反射机制实现的。拦截是aop的一种实现策略。
        在webWork中,拦截器是动态拦截Action调用的对象,提供了一种机制使开发者可以定义在一个Action执行的前后执行的代码,也可以在一个Action执行前阻止其
  执行。同时,也提供了一种可以提取Action中可重用的部分的方式。
        拦截器从Action中抽出了很多功能,大量减少了Actin中的代码,抽取出的公共方法可以更好的重用。
        当我们提交对Action的请求时,ServletDispatcher会根据请求,调度并执行相应的Action;在此Action执行之前,调用被Interceptor截取,Interceptor
     在Action执行前后执行。

二、在ssm中的实现

 SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的。主要有两种方式:
 第一种: 定义的Interceptor类  实现Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring 已经提供的实现了
          HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;
 第二种: 定义的Interceptor类, 实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。

三、在springboot中的实现

 第一种: 创建类 LogCostInterceptor  实现  HandlerInterceptor 接口;
          创建配置类WebConfiguration 继承 WebMvcConfigurationSupport (或者 WebMvcConfigurerAdapter);添加 @Configuration注解;

@Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {

    private Logger logger = LoggerFactory.getLogger(WebConfiguration.class);
    
    @Override
    public void addInterceptors(InterceptorRegistry registry){
            // 多个拦截器组成一个拦截器链
            // addPathPatterns 用于添加拦截规则
            // excludePathPatterns 用户排除拦截
            registry.addInterceptor(new LogCostInterceptor()).addPathPatterns().excludePathPatterns("/swagger-ui.html");
    }

}
四、 拦截器中三个方法的详细解释

     SpringMvc的过滤器是链式的,在一个应用中或者一个请求中可以有多个Interceptor,执行顺序按照声明中的顺序执行,先执行每个过滤器中的preHandle方法。
 1) preHandle  在请求controller之前执行,可以在方法中进行一些初始化操作或者是对当前请求的一个预处理,也可以设置一些判断决定请求是否要继续下去。
                返回结果如果是true,则执行后续的Interceptor中的preHandle和controller,
                如果是false,表示请求结束。
 2) postHandle  在preHandle执行为true后,执行该方法。在controller执行之后,在DispatcherServlet进行视图返回渲染之前被调用;在这个方法中可以对
                  ModelAndView对象进行处理。postHandle的执行顺序在链式中和preHandle的执行顺序是相反的,先执行preHandle的过滤器的postHandle后执行。
 3) afterCompletion  preHandle执行为true后执行。 该方法在整个请求结束之后,在DispatcherServlet渲染了对应的视图之后执行。
                      作用: 进行资源清理工作。

二 拦截器

一 、定义:

   filter 实现了 javax.servlet.filter接口的服务器端程序;

二、 用途:

   设置字符集、控制权限、控制转向、业务逻辑判断等

三、 工作原理:

   在web.xml文件配置需要拦截的客户端请求,它会帮你拦截到请求,此时你可以对请求或相应统一设置编码、简化操作;同时可以进行逻辑判断,如用户是否已经登录、有没有权限访问该页面等等。
   随着web应用启动而启动,只需要初始化一次,以后就可以拦截相关请求,只有当web应用停止或重新部署的时候才销毁。
   Filter 主要用户对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。

四、 流程:

   filter对用户请求进行预处理,将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

五、 用处:

    在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
    根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
    在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
    根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

六、 种类:

    用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
    日志Filter:详细记录某些特殊的用户请求。
    负责解码的Filter:包括对非标准编码的请求解码。
    能改变XML内容的XSLT Filter等。
    Filter可以负责拦截多个请求或响应;一个请求或响应也可以被多个Filter拦截。

七、 使用:

       1 创建Myfilter类继承Filter
          重写 init 和 doFilter
        ② 在init方法中初始化自定义参数,参数名称可以设置为此时的 url,对其执行过滤,也就是放过; 
        ③ 在doFilter中可以进行认证鉴权处理,之后执行相应的逻辑;
                       也可以进行跨域的设置;
           在doFilter中 chain.doFilter(req, res)是对请求和响应处理的分界线,执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理
         1)第一种方案
           a: 在Myfilter类 添加注解  @WebFilter ,可以添加 @Order(1)多个Myfilter的时候 按照顺序执行
              @WebFilter的一些参数值
                  (    filterName = "Myfilter", urlPatterns = "/snow/api/*",
                        initParams = {  @WebInitParam(name = "url", value = "/snow/api/login")}
                    )
              filterName 拦截的地址   initParams 放过的地址,不需要检测
           b: 在springboot的启动类上添加 @ServletComponentScan
          2)第二种方案
            a:  在Myfilter类 添加注解  @Component,交给spring容器处理
            b:  创建一个config类,添加注解 
                 

@Configuration
public class config {

@Bean
public FilterRegistrationBean webAuthFilterRegistration() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(myfilte());
    registration.setName("Myfilter");
    registration.addUrlPatterns("/snow/api/*");
    registration.addInitParameter("url", "/snow/api/login");
    registration.setOrder(0); //设置顺序
    return registration;
}

@Bean
public Filter myfilter() {
    return new Myfilter();
}

}

三 过滤器和拦截器的比较

   一、区别和不同
         相同:都是AOP编程思想的实现。
         不同点: 
        使用范围不同              过滤器只能使用再web应用程序,也就是在servlet容器中; 拦截器即可以使用在web应用中,也可以使用在 
                                         javaSE的各种环境。
        使用的资源不同           拦截器是spring的组件,被spring管理,可以使用spring的任何资源包括:Servive对象、事务管理、数据源等, 
                                         通过IOC注入到容器即可。过滤器不可以。
        使用的深度(范围)不同     过滤器只在Servlet前后起作用;拦截器可以深入到方法前后、异常抛出前后等,具有更大的弹性。 
        执行顺序不同             Filter是被Server(比如tomcat、netty)调用; Interceptor被spring调用; 所以Filter在Interceptor前面执行。
         使用选择                   在spring架构的实现中,优先选择使用拦截器。
   二、 过滤器和拦截器的执行流程图

网友评论

登录后评论
0/500
评论
坎布里奇
+ 关注