Java使用拦截器的两种方式

2022-02-09 16:53:37 浏览数 (1)

拦截器是个好东西,之前用到过,现在记录一下,供以后参考使用!

其一,使用org.aspectj.lang.annotation.Aspect

先上代码:

代码语言:javascript复制
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:方法执行之前的处理逻辑;

可以看出来,这个不是真正意义上的拦截器,而只是功能来说是拦截数据(面向切面编程);

由于之前使用拦截器时发现,拦截器会读取数据后不释放,导致拦截后数据无法流转!其形式如以下代码;

代码语言:javascript复制
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

先上代码:

代码语言:javascript复制
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的使用中需要配置一下:

代码如下:

代码语言:javascript复制
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");
        }
    }

    
}

0 人点赞