过滤器 拦截器 AOP切面
拦截颗粒:过滤器 > 拦截器 > AOP切面 【精细度反之】
拦截顺序:过滤器 》拦截器 》AOP切面
1.过滤器
基于函数回调,依赖于servlet容器,无法注入Bean;拦截URL,拦截的最前沿,适合公用性强的拦截逻辑,对服务性能影响最小
简单实现@"暴力屏蔽Cors跨越",过滤器的核心方法是doFilter,通过调整req与res实现过滤功能。
@Component
public class CorsFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD");
response.setHeader("Access-Control-Max-Age", "3000");
response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");
chain.doFilter(req, res);
}
}
2.拦截器
基于java反射,不依赖于servlet容器,可以注入Bean;拦截URL,在过滤器之后拦截
简单实现@"登录拦截",拦截器的核心方法是preHandle(前置拦截controller前)、postHandle(后置拦截 页面渲染之前)、afterCompletion(最终拦截 用于销毁关闭资源),通过调整req与res实现过滤功能。
public class LoginHandlerInterceptor implements HandlerInterceptorAdapter {
@Resource
private LoginCache loginCache;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Cookie[] cookies = request.getCookies();
if (null != cookies && cookies.length >= 1) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) {
return loginCache.exist(cookie.getValue());
}
}
}
request.getRequestDispatcher("/").forward(request, response);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
super.afterCompletion(request, response, handler, ex);
}
}
3.AOP切面
基于java反射,拦截包、类、方法、参数
简单实现@"controller日志"。
@Component
@Aspect
@Slf4j
public class ControllerLogAop {
@Around("execution(public * com.xxx.controller.*.*(..))")
public Object aroundController(ProceedingJoinPoint point) throws Throwable {
return writeLog(point);
}
private Object writeLog(ProceedingJoinPoint point) throws Throwable {
String className = point.getTarget().getClass().getName();
String methodName = point.getSignature().getName();
String reqUrl = StringUtils.EMPTY;
String reqMethod = StringUtils.EMPTY;
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
if (request != null) {
reqUrl = request.getRequestURL().toString();
reqMethod = request.getMethod();
}
long beginTime = System.currentTimeMillis();
Object result = null;
Exception ex = null;
try {
result = point.proceed();
return result;
} catch (Exception e) {
ex = e;
throw e;
} finally {
long costTime = System.currentTimeMillis() - beginTime;
if (ex != null) {
log.error("[url: {}][method: {}][className: {}][methodName: {}][cost: {} ms][args: {}][发生异常]", reqUrl, reqMethod, className, methodName, costTime, point.getArgs(), ex);
} else {
log.info("[url: {}][method: {}][className: {}][methodName: {}][cost: {} ms][args: {}][return: {}]", reqUrl, reqMethod, className, methodName, costTime, point.getArgs(), new Gson().toJson(result));
}
}
}
}