上图为在web项目中,在处理request请求时得处理顺序
在项目中我们改怎么使用呢?
Filter过滤器
/**
* Created by GAOMINGQIAN on 2017/12/10.
*<pr>
* Filter只能获取到请求的request和response。获取不到其他的信息
* 因为Filter属于J2EE的内容,不知道spring
* 会拦截所有的请求
*</pr>
*
*/
//@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 servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("time filter start");
long start=new Date().getTime();
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("time filter end:"+(new Date().getTime()-start));
System.out.println("time filter finsh");
}
//销毁时调用
@Override
public void destroy() {
System.out.println("time filter destory");
}
}
上述内容中有一个@Component注解,当我们不想使用时或者更细的粒度拦截,需要在config类中进行注册
//配置一个过滤器
@Bean
public FilterRegistrationBean timeFilter() {
//filter注册用的bean
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
TimeFilter timeFilter = new TimeFilter();
filterRegistrationBean.setFilter(timeFilter);
List<String> urls = new ArrayList<>();
urls.add("/*");
//设置filter对那些请求有作用,这里设置的是对所有的请求都有作用
filterRegistrationBean.setUrlPatterns(urls);
return filterRegistrationBean;
}
Interceptor拦截器
/**
* Created by GAOMINGQIAN on 2017/12/10.
*/
public class TimeInterceptor implements HandlerInterceptor {
//该方法的返回值决定后续的方法是否执行(controller中的方法)
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("preHandle");
//获取controller类名称
System.out.println(((HandlerMethod) o).getBean().getClass().getName());
//获取执行method的名字
System.out.println(((HandlerMethod)o).getMethod().getName());
httpServletRequest.setAttribute("startTime", new Date().getTime());
return true;
}
//当controller抛出异常时,该方法不会被调用
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
long start = (Long) httpServletRequest.getAttribute("startTime");
System.out.println("time interceptor耗时" + (new Date().getTime() - start));
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("afterCompletion");
long start = (Long) httpServletRequest.getAttribute("startTime");
System.out.println("time interceptor耗时" + (new Date().getTime() - start));
//当无异常的时候,e的值为null,有自定义异常时,也会为Null
System.out.println(e);
}
}
需要在配置类中声明才能使用,继承WebMvcConfigurerAdapter
//告诉spring这是一个配置类
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册当前的拦截器
registry.addInterceptor(new TimeInterceptor());
}
}
Aspect切片使用
/**
* Created by GAOMINGQIAN on 2017/12/10.
*/
@Aspect
@Component
public class TimeAspect {
//around中的execution中的内容代表对哪些方法进行拦截
@Around("execution(* study.security.web.controller.UserController.*(..))")
public Object handlerControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("time aspect start");
//获取执行方法的参数
Object[] args = pjp.getArgs();
long start = new Date().getTime();
//执行拦截的方法 result为拦截方法的返回值
Object result = pjp.proceed();
System.out.println("time aspect 耗时:" + (new Date().getTime() - start));
return result;
}
}
ControllerAdvice,主要用于异常处理的控制器
/**
* Created by GAOMINGQIAN on 2017/12/10.
*/
@ControllerAdvice
public class ControllerHandlerException {
@ExceptionHandler(UserNotExistException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, Object> handleUserNotExistException(UserNotExistException ex) {
Map<String, Object> result = new HashedMap();
//放置需要响应的内容
result.put("message",ex.getMessage());
return result;
}
}
优缺点介绍:
Filter过滤器:可以拿到request,response但是拿不到处理方法的信息
Interceptor拦截器:可以拿到request,response,也可以拿到处理方法的信息,但是拿不到处理方法参数的值
Aspect切片:可以拿到处理方法的所有信息,但是拿不到request,response
####################################################################################################
spring的Aspect,Filter、Interceptor、ControllerAdvice区别
2018年02月11日 17:02:43 肖先森是摩羯座 阅读数:1680
1、filter,这是java的过滤器,和框架无关的,是所有过滤组件中最外层的,从粒度来说是最大的。
配置方式,有直接实现Filter+@component,@Bean+@configuration(第三方的filter)
2、interceptor,spring框架的拦截器
配置方式,@configuration+继承WebMvcConfigurationSupport类添加过滤器。
3、aspect,可以自定义要切入的类甚至再细的方法,粒度最小。加个注解用效果更佳。
4、controllerAdvice,是controller的增强,和ExceptionHandler一起用来做全局异常。
总结:
filter:和框架无关,可以控制最初的http请求,但是更细一点的类和方法控制不了。
interceptor:可以控制请求的控制器和方法,但控制不了请求方法里的参数。
aspect : 可以自定义切入的点,有方法的参数,但是拿不到http请求,可以通过其他方式如RequestContextHolder获得。
最后:
从网上找的图片: