ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

拦截器详解

2021-10-26 17:00:30  阅读:131  来源: 互联网

标签:拦截器 HttpServletResponse 调用 import servlet public 详解


网络上关于Interceptor的文章,但感觉内容都大同小异,而且知识点零零散散,不太方便阅读。因此,整理一篇关于拦截器的文章,在此分享给大家,以供大家参考阅读。

1.概念

  java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。在AOP中,拦截器用于在某个方法或者字段被访问之前进行拦截,然后再之前或者之后加入某些操作。

       谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

2.拦截器的原理
      大部分时候,拦截器方法都是通过代理的方式来调用的。是基于反射实现的,Struts2的拦截器实现相对简单。当请求到达Struts2的ServletDispatcher时,Struts2会查找配置文件,并根据配置实例化相对的拦截器对象,然后串成一个列表(List),最后一个一个的调用列表中的拦截器。Struts2的拦截器是可插拔的,拦截器是AOP的一个实现。Struts2拦截器栈就是将拦截器按一定的顺序连接成一条链。在访问被拦截的方法或者字段时,Struts2拦截器链中的拦截器就会按照之前定义的顺序进行调用。

3.自定义拦截器的步骤
  1)、创建我们自己的拦截器类并实现 HandlerInterceptor 接口。
  2)、创建一个Java类继承WebMvcConfigurerAdapter,并重写 addInterceptors 方法。
  3)、实例化我们自定义的拦截器,然后将对像手动添加到拦截器链中(在addInterceptors方法中添加)。

4.代码示例

IndexInterceptor.java类代码:

package com.example.interceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

public class IndexInterceptor implements HandlerInterceptor{

  @Override

  public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)

      throws Exception {

    System.out.println(">>>IndexInterceptor>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");

  }

  @Override

  public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)

      throws Exception {

    System.out.println(">>>IndexInterceptor>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");

  }

  @Override

  public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {

     System.out.println(">>>IndexInterceptor>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");

     // 只有返回true才会继续向下执行,返回false取消当前请求

     return true;

  }

}

IndexInterceptor2.java类代码:

package com.example.interceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

public class IndexInterceptor2 implements HandlerInterceptor{

  @Override

  public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)

      throws Exception {

    System.out.println(">>>IndexInterceptor2>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");

  }

  @Override

  public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)

      throws Exception {

    System.out.println(">>>IndexInterceptor2>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");

  }

  @Override

  public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {

     System.out.println(">>>IndexInterceptor2>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");

     // 只有返回true才会继续向下执行,返回false取消当前请求

     return false;

  }

}

SimpleWebAppConfigurer.java类代码:

package com.example.config;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.example.interceptor.IndexInterceptor;

import com.example.interceptor.IndexInterceptor2;

//只要能被springboot扫描到即可

@Configuration

public class SimpleWebAppConfigurer extends WebMvcConfigurerAdapter{

  @Override

  public void addInterceptors(InterceptorRegistry registry) {

    // 多个拦截器组成一个拦截器链

    // addPathPatterns 用于添加拦截规则

    // excludePathPatterns 用户排除拦截

    registry.addInterceptor(new IndexInterceptor()).addPathPatterns("/**");

    registry.addInterceptor(new IndexInterceptor2()).addPathPatterns("/**");

    super.addInterceptors(registry);

  }

}

5.应用场景

1、日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。

2、权限检查:如登陆检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。

3、性能监控:典型的是慢日志

6.注意点

在一个工程中,可以配置多个拦截器,使用多个拦截器,则要注意的是 :多个拦截器使用的时候,prehandler是顺序执行的,而posthandler和afterhandler是倒序执行的;

所以 :如果统一日志处理器拦截器,需要改拦截器prehandler一定要返回true,且将它放在拦截器配置的第一个位置;

      如果登陆认证拦截器,放在拦截器的配置中的第一个位置(有日志处理的话,放在日志处理下面);

      如果有权限校验拦截器,则放在登陆拦截器之后,因为登陆通过后,才可以进行校验权限;

标签:拦截器,HttpServletResponse,调用,import,servlet,public,详解
来源: https://www.cnblogs.com/wffzk/p/15466619.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有