Java使用拦截器的两种方式
拦截器是个好东西,之前用到过,现在记录一下,供以后参考使用!
其一,使用org.aspectj.lang.annotation.Aspect
先上代码:
package com.test.interceptors.aop; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; @Aspect @Component public class TaskAspect { private static final Logger logger = LoggerFactory.getLogger(TaskAspect.class); @Pointcut("execution(* com.test.controller.TestController.addTask(..))") private void addTaskAction(){}; private ThreadLocal<String> tLocal = new ThreadLocal<String>(); @Before("execution(* com.test.controller.TestController.addTask(..)) && args(id,userId,name)") public void getInterview(String moid,int taskType,String otherAttr, String actDefName, String taskName,String userId){ tLocal.set(moid); } @Around("addTaskAction()") public Object aroundInterviewTask(ProceedingJoinPoint pjp) throws Throwable{ Object[] args = pjp.getArgs(); Object retVal = pjp.proceed(args); try { //获取参数 String id = args[0].toString(); String name = args[2].toString(); //业务逻辑处理 } catch (Throwable e) { //异常处理 } return retVal; } @AfterReturning(returning="result",pointcut="addTaskAction()") public void addCount(Object result){ } }
@Aspect:切面
@Pointcut:指定需要拦截的方法;
@Arround: 当拦截到方法被调用时的处理逻辑,可获取方法参数;
@AfterReturning:方法执行完成后的处理逻辑
@Before:方法执行之前的处理逻辑;
可以看出来,这个不是真正意义上的拦截器,而只是功能来说是拦截数据(面向切面编程);
由于之前使用拦截器时发现,拦截器会读取数据后不释放,导致拦截后数据无法流转!其形式如以下代码;
package com.test.interceptors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class TestInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub //System.out.println("=postHandle=============="); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub //System.out.println("拦截url==="+request.getRequestURI()); } }
其二,org.springframework.web.bind.annotation.ControllerAdvice
先上代码:
package com.test.interactive.interceptors; import java.io.IOException; import java.lang.reflect.Type; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.MethodParameter; import org.springframework.http.HttpInputMessage; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; @ControllerAdvice(assignableTypes = { TestRSImpl.class }) public class TestInterceptor implements HandlerInterceptor, RequestBodyAdvice { private static final Logger logger = LoggerFactory.getLogger(TestInterceptor.class); @Override public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { return methodParameter.getMethod().getName().equals("submit");; } @Override public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { return body; } @Override public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException { return inputMessage; } @Override public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { try{ //业务处理逻辑 } catch (Throwable e) { logger.error("", e); } return body; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { try { } catch (Throwable e) { logger.error("", e); } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // nothing to do } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // nothing to do } }
这个是真正意义上的拦截器;
supports:需要拦截的方法名称
afterBodyRead:具体业务处理逻辑
在SpringBott的使用中需要配置一下:
代码如下:
public class MediajobAutoConfiguraiotn extends WebMvcConfigurerAdapter{ @Autowired private CheckMediaJobInterceptor checkMediaJobInterceptor; @Value("${checkMediaJob.interceptor.enabled:true}") private boolean checkMediaJobEnabled; @Override public void addInterceptors(InterceptorRegistry registry) { if (checkMediaJobEnabled) { registry.addInterceptor(checkMediaJobInterceptor).addPathPatterns( // "/api/url"); } } }