我们用拦截器 和过滤器 分别实现一个需求: 那就是在运行一次请求所用了多少的时间
//@Component
@Slf4j
public class TimeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("timeFile init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("timeFilter start");
Long startTime = new Date().getTime();
filterChain.doFilter(servletRequest,servletResponse);
log.info("共用时间:{}",new Date().getTime() - startTime);
log.info("timeFilter finish");
}
@Override
public void destroy() {
log.info("timeFile end");
}
}
实现了Filter接口,init->filter初始化,在tomcat启动的时候就会运行
doFilter()->里面有三个参数,request,response就不多说了, filterChain.doFilter();就是放行的。
如果你还想配置过滤器:
(SpringBOOT)我们新建一个类 WebConfig
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean timeFilter(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new TimeFilter());
List urlPartterns = new ArrayList<>();
urlPartterns.add("/*");
filterRegistrationBean.setUrlPatterns(urlPartterns);
return filterRegistrationBean ;
}
}
我们把这个FilterRegistrationBean写进容器 这样就可以起到作用了
@Component
@Slf4j
public class TimeInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
log.info("preHandler..");
log.info("进入的类名:{}", ((HandlerMethod) handler).getBean().getClass().getName());
log.info("进入的方法名:{}", ((HandlerMethod) handler).getMethod().getName());
httpServletRequest.setAttribute("current_time", new Date().getTime());
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
log.info("进入postHandler...");
Long current_time = (Long) httpServletRequest.getAttribute("current_time");
log.info("运行时间为:{}", Math.abs(current_time - (new Date().getTime())));
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
log.info("进入afterCompletion......");
Long current_time = (Long) httpServletRequest.getAttribute("current_time");
log.info("运行时间为:{}", Math.abs(current_time - (new Date().getTime())));
log.info("异常为:{}",e);
}
}
定义一个拦截器 实现HandlerInterceptor
preHandler()-->注意里面有一个参数 那就是Object handler 这个参数就是我们即将运行的那个方法
我们需要把这个参数转换为 HandlerMethod 在进行操作 返回true的话就是放行,返回false的话就是拦截。
postHandler()--->这个方法如果运行的方法抛出的异常那么这个postHandler()方法就不会在运行。
afterCompletion()--->这个方法无论一定会执行 , 如果有异常 可以打印出。
好 ,最后一步我们需要在webconfig配置
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private TimeInterceptor timeInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(timeInterceptor);
}
}
这个webConfig需要继承 WebMvcConfigurerAdapter 并且覆盖addInterceptor方法 。
@Aspect
@Component
@Slf4j
public class TimeAspect {
@Around("execution(public * com.yumin.security.yuminsecuritydemo.web.controller.UserController.*(..))")
public Object handlerControllerMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
log.info("切面的方法进入");
Object[] args = proceedingJoinPoint.getArgs();
for (Object o :
args) {
System.out.println(o);
}
Long startTime = new Date().getTime();
Object proceed = proceedingJoinPoint.proceed();
log.info("proceed:{}",((Person)proceed).getName());
log.info("time aspect耗时:{}", new Date().getTime() - startTime);
return proceed;
}
}
需要主要的是:
在写这个Aspect里面的方法的参数为 ProceedingJointPoint
这里面的getArgs()是得到参数
proceedJointPoint.getPreceed()得到的是结果对象 return proceed;这样才可以