版权声明:士,不可以不弘毅,任重而道远 https://blog.csdn.net/superbeyone/article/details/84504604
文章目录
Spring Boot RESTful API拦截(过滤器,拦截器,切片)
1. 过滤器(Filter)
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 添加方式二
- 添加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");
}
}
- 添加配置类
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;
}
}
Interceptor
和Filter
的执行顺序:
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