过滤器(Filter)
自定义Filter需要实现了javax.servlet的Filter接口。
可以直接在类上加@Component注解 //所有的Url都会过过滤器
或者在配置类(@Configuration注解标注的类)中加
@Bean
FilterRegistrationBean registrationBean= new FilterRegistrationBean (){
MyFilter myFilter = new MyFilter();
List url = new ArrayLister<>();
urls.add("/*"); //对哪些路径起作用
registrationBean.setUrlPatterns(urls);
return registrationBean;
}
在doFilter处理方法中只能拿到request response。 但是不知道是具体哪个接口来处理对应的请求
拦截器(Interceptor)
自定义拦截器需要实现HandlerInterceptor接口。
接口中自定义实现的三种方法:preHandle()、postHandle()、afterCompletion()。
preHandle()、postHandle() 像是Filter中doFilter()分开了。
不管抛错没有都会进到afterCompletion方法
拦截器会拦截所有的控制器包括spring里自带的。
需要在类上加@Component注解并且需要在配置类中声明。
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private TimeInterceptor timeInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(timeInterceptor);
}
}
拦截器没法拿到真正参数的值
切片(Aspect)
原理是Sping 的aop
自定义切片需要在类上加@Aspect 和 @Component注解
需要我们声明切入点(说明哪些方法 什么时候切片起作用)
//@Before是在所拦截方法执行之前执行一段逻辑
//@After是在所拦截方法执行之后执行一段逻辑。
//@Around是可以同时在所拦截方法的前后执行一段逻辑
@Aspect
@Component
public class TimeAspect {
Logger logger = LoggerFactory.getLogger(getClass());
//Controller 中的方法
@Around("execution(* com.zlf.mysprin.rest.TestEndpoints.*(..))")
public Object handleControllerMethod(ProceedingJoinPoint proceedingJoinPoint) {
logger.info("aspect");
Object result = null;
try {
Object[] args = proceedingJoinPoint.getArgs();
for (Object o : args) {
logger.info("method arg:{}", o);
}
Long start = new Date().getTime();
result = proceedingJoinPoint.proceed();
logger.info("aspect use time:{}", new Date().getTime() - start);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return result;
}
}
切片可以拿到请求方法的传入参数值,拿不到原始的HTTP请求和响应的对象。
拦截起作用的顺序:Filter Interceptor ControllerAdvice Aspect Controller
获取异常的顺序相反