Filter
javax.servlet.filter 是java sevlet规范定义的接口,定义了3个方法
public void init(FilterConfig filterConfig) throws ServletException;
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException;
public void destroy();
filter 的缺点在于无法拿到具体请求的哪个controller的哪个方法
Interceptor
通过org.springframework.web.servlet.HandlerInterceptor接口实现
该接口是由SpringMVC提供,有三个方法
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
该方式可以拿到请求的具体类名和方法
((HandlerMethod)handler).getBean().getClass().getName()
((HandlerMethod)handler).getMethod().getName()
但是这种方式拿不到方法上的具体参数值
AOP
可以通过ProceedingJoinPoint 拿到具体的参数值
但是无法获取HttpServletRequest 和HttpServletResponse 对象
@Around("execution(* com.jerio.web.controller.UserController.*(..))")
public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
for (Object arg : args) {
System.out.println("arg is "+arg);
}
// 获取类名
pjp.getSignature().getDeclaringTypeName()
// 获取方法名
pjp.getSignature().getName()
}
如果想要拿到Request对象,需要借助Spring提供的org.springframework.web.context.request.RequestContextHolder,该类使用ThreadLocal保存了本次请求的相关信息
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
网友评论