Spring Boot RESTful API拦截(过滤器,拦截器,切片)

版权声明:士,不可以不弘毅,任重而道远 https://blog.csdn.net/superbeyone/article/details/84504604


Spring Boot RESTful API拦截(过滤器,拦截器,切片)

1. 过滤器(Filter)

1.1 添加方式一

  1. 添加Filter
import javax.servlet.*;
import java.io.IOException;

/**
 * @Project: tdt-security
 * @ClassName: TimerFilter
 * @Author: Mr.superbeyone
 * @Time: 2018-11-25 23:28
 * @Description: 过滤器
 **/
@Component
public class TimeFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("time filter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("time filter start");
        long start = System.currentTimeMillis();
        chain.doFilter(request, response);
        System.out.println("执行了:" + (System.currentTimeMillis() - start) + "毫秒");
        System.out.println("time filter finish");
    }

    @Override
    public void destroy() {
        System.out.println("time filter destroy");
    }
}

1.2 添加方式二

  1. 添加Filter
import javax.servlet.*;
import java.io.IOException;

/**
 * @Project: tdt-security
 * @ClassName: TimerFilter
 * @Author: Mr.superbeyone
 * @Time: 2018-11-25 23:28
 * @Description: 过滤器
 **/
 
public class TimeFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("time filter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("time filter start");
        long start = System.currentTimeMillis();
        chain.doFilter(request, response);
        System.out.println("执行了:" + (System.currentTimeMillis() - start) + "毫秒");
        System.out.println("time filter finish");
    }

    @Override
    public void destroy() {
        System.out.println("time filter destroy");
    }
}
  1. 添加配置类WebConfig
import com.tdt.security.filter.TimeFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;

/**
 * @Project: tdt-security
 * @ClassName: WebConfig
 * @Author: Mr.superbeyone
 * @Time: 2018-11-25 23:36
 * @Description: 自定义配置类
 **/
@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean timeFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        TimeFilter timeFilter = new TimeFilter();

        registrationBean.setFilter(timeFilter);

        ArrayList<String> urls = new ArrayList<>();
        urls.add("/*");
        registrationBean.setUrlPatterns(urls);
        return registrationBean;
    }
}

方式一与方式二的区别
方式二可以引入第三方过滤器,算是方式一的扩展

2. 拦截器(Interceptor)

Spring框架本身提供,能够获得请求是从哪个控制器和哪个方法传来的,即真正处理请求方法的对象。

import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Project: tdt-security
 * @ClassName: TimeInterceptor
 * @Author: Mr.superbeyone
 * @Time: 2018-11-26 19:25
 * @Description: 自定义拦截器
 **/
@Component
public class TimeInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        System.out.println(((HandlerMethod) handler).getBean().getClass().getName());
        System.out.println(((HandlerMethod) handler).getMethod().getName());
        request.setAttribute("startTime", System.currentTimeMillis());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandler");
        Long startTime = (Long) request.getAttribute("startTime");
        System.out.println("执行时间为:\t" + (System.currentTimeMillis() - startTime) + "毫秒");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("completion");
        Long startTime = (Long) request.getAttribute("startTime");
        System.out.println("执行完Interceptor时间为:\t" + (System.currentTimeMillis() - startTime) + "毫秒");
        System.out.println("ex:\t" + ex);
    }
}
import com.tdt.security.filter.TimeFilter;
import com.tdt.security.interceptor.TimeInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.ArrayList;

/**
 * @Project: tdt-security
 * @ClassName: WebConfig
 * @Author: Mr.superbeyone
 * @Time: 2018-11-25 23:36
 * @Description: 自定义配置类
 **/
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    TimeInterceptor timeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }

    @Bean
    public FilterRegistrationBean timeFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        TimeFilter timeFilter = new TimeFilter();

        registrationBean.setFilter(timeFilter);

        ArrayList<String> urls = new ArrayList<>();
        urls.add("/*");
        registrationBean.setUrlPatterns(urls);
        return registrationBean;
    }
}

InterceptorFilter的执行顺序:
在这里插入图片描述

3. 切片(Aspect)

在这里插入图片描述
pom依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * @Project: tdt-security
 * @ClassName: TimeAspect
 * @Author: Mr.superbeyone
 * @Time: 2018-11-26 19:58
 * @Description: 自定义切片
 **/
@Aspect
@Component
public class TimeAspect {
    @Around("execution(* com.tdt.security.web.controller.UserController.*(..))")
    public Object handlerControllerMethod(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("time aspect start");

        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            System.out.println("arg is:\t" + arg);
        }
        Object object = joinPoint.proceed();
        System.out.println("time aspect end");

        return object;
    }
}

执行结果:
在这里插入图片描述

在这里插入图片描述
更多切面语法

4. 总结

4.1 优缺点

4.1.1 Filter

可以拿到原始的Http请求和响应的信息,只能获得其请求和响应携带的参数,但是却拿不到真正处理请求的控制器和方法的信息。

4.1.2 Interceptor

既可以拿到原始的Http请求和响应的信息,也能拿到真正处理请求的方法信息,但是拿不到方法被调用时,真正调用的参数的值。

4.1.3 Aspect

可以拿到方法被调用时真正传进来的参数的值,但是却拿不到原始的Http请求和响应。

4.2 执行顺序

在这里插入图片描述
Filter -> Interceptor -> ControlerAdvice -> Aspect -> Controller

在这里插入图片描述
ControlerAdvice 传送门

github 项目源码地址

猜你喜欢

转载自blog.csdn.net/superbeyone/article/details/84504604