SpringBoot 共有三种拦截http请求方式Filter,interceptor和aop 。
1、FIlter
使用Filter的时候需要在Application启动类上加入@ServletComponentScan注解
import JAVAx.servlet.*;import javax.servlet.annotation.WebFilter;import java.io.IOException;/** * 在SpringBoot中通过注解注册的方式简单的使用Filter * @author rayfoo */@WebFilter(urlPatterns = "/*", filterName = "MyFilter")public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("MyFilterFilter初始化中");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("MyFilter开始进行过滤处理");//调用该方法后,表示过滤器经过原来的url请求处理方法chain.doFilter(request, response);System.out.println("MyFilter处理后的操作");}@Overridepublic void destroy() {System.out.println("MyFilterFilter销毁中");}}上述代码中,重写了Filter的三个方法,分别是:
init:在此Filter被创建时执行
doFilter:处理Filter的真正业务逻辑,可以在这个方法中对请求进行放行,在放行前后都可以执行代码,也可以在此方法中进行重定向和请求转发,但是一旦使用了请求转发、重定向,抛出异常,出现异常,被拦截的路径对应的业务方法就不会被执行 。
destory:在此FIlter被销毁时执行
2、Interceptor
Interceptor依赖于web框架,我们经常在Spring MVC中用到该配置,在这个场景下Interceptor 就依赖于SpringMVC框架 。
使用Interceptor之前要先创建类并实现HandlerInterceptor接口
import org.springframework.lang.Nullable;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {/*** 在业务处理器处理请求之前被调用 。预处理,可以进行编码、安全控制、权限校验等处理* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("MyInterceptor方法执行之前...");return true;}/*** 在业务处理器处理请求执行完成后,生成视图之前执行 。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView* @param request* @param response* @param handler* @param modelAndView* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {System.out.println("MyInterceptor回调操作...");}/*** 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 。返回处理(已经渲染了页面)* @param request* @param response* @param handler* @param ex* @throws Exception*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {System.out.println("MyInterceptor方法执行之后...");}}创建完实现类还需要注册Interceptor
在SpringBoot2中,建议使用的注册拦截器的方法有如下两种:
1)实现WebMvcConfigurer接口
2)继承WebMvcConfigurerAdapter类(此类也是实现了WebMvcConfigurer)
下面介绍一下实现WebMvcConfigurer方法注册拦截器
import com.xa.filter.MyInterceptor;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic class MyConfigurer implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {//1.得到自定义的拦截器InterceptorRegistration interceptor = registry.addInterceptor(new MyInterceptor());//2.需要拦截的路径 /**所有资源都拦截interceptor.addPathPatterns("/**");//3.设置不拦截的路径 (登录页需要的和静态资源)interceptor.excludePathPatterns("/","/index.html","/login","/css/**","/img/**","/js/**");}}3、AOP
使用AOP首先要引入jar包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.1.1.RELEASE</version> </dependency>定义切面
import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.util.Arrays;@Aspect@Component@Order(1) //指定切面类执行顺序,数字越小越先执行public class MyAspect {/*** 定义那个包下的执行 面向切换* 该示例 实现 所有controller 包下的方法执行的切面* 第一个*含义是:代表所有类型的返回值* 第二个*是代表com.mall.web.controller包下的所有类* 第三个是类下的所有方法,括号中两个点表示任意个形参 */@Pointcut("execution(public * com.*.controller.*.*(..))")public void webLog(){}/*** 请求之前 进入控制之前 执行,但是在拦截器之后执行* @param joinPoint* @throws Throwable*/@Before("webLog()")public void deBefore(JoinPoint joinPoint) throws Throwable {// 接收到请求,记录请求内容ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();// 记录下请求内容System.out.println("MyAspectURL : " + request.getRequestURL().toString());System.out.println("MyAspectHTTP_METHOD : " + request.getMethod());System.out.println("MyAspectIP : " + request.getRemoteAddr());System.out.println("MyAspectCLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());System.out.println("MyAspectARGS : " + Arrays.toString(joinPoint.getArgs()));}/*** 控制器执行之后执行,得到控制器方法的返回值* @param ret* @throws Throwable*/@AfterReturning(returning = "ret", pointcut = "webLog()")public void doAfterReturning(Object ret) throws Throwable {// 处理完请求,返回内容System.out.println("MyAspect方法的返回值 : " + ret);}//后置异常通知@AfterThrowing("webLog()")public void throwss(JoinPoint jp){System.out.println("MyAspect方法异常时执行.....");}//后置最终通知,final增强,不管是抛出异常或者正常退出都会执行@After("webLog()")public void after(JoinPoint jp){System.out.println("MyAspect方法最后执行.....");}//环绕通知,环绕增强,相当于 请求方法的拦截器@Around("webLog()")public Object arround(ProceedingJoinPoint pjp) {System.out.println("MyAspect方法环绕start....."); // 最先执行try {Object o =pjp.proceed();System.out.println("MyAspect方法环绕proceed,结果是 :" + o); // 最后执行return o;} catch (Throwable e) {e.printStackTrace();return null;}}}
推荐阅读
- Mysql删除数据表的三种方式详解
- 三种人坚决不能吃桂花,这种人坚决不能吃
- SpringBoot集成多数据源
- SpringBoot整合RabbitMQ四种交换机类型详解
- 发型|女人不到40岁,前3种发型别尝试,后三种发型值得拥有
- 程序员标配Springboot!终于有人把SpringBoot讲的通俗易懂了
- LVS三种模式的实现原理、配置及优点缺点详解
- 从网络请求过程看OkHttp拦截器
- SpringBoot事件监听:应用监听接口的使用
- 恒星往往是静止的而行星则围绕恒星运动 恒星行星卫星三种天体运动的关系是什么
