一、拦截器的作用

  将通用的代码抽取出来,达到复用的效果。比如可以用来做日志记录、登录判断、权限校验等等

 

二、如何实现自定义拦截器

1)创建自定义拦截器类并实现HandlerInterceptor类

/**
 * @author zhangboqing
 * @date 2019-07-28
 */
public class MyInterceptor implements HandlerInterceptor {

    /**
     * 执行Controller方法之前,调用
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
        //返回false,请求将被拦截。放回true代表放行
        return false;
    }

    /**
     * 执行Controller方法之后,响应给前端之前,调用
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 响应给前端之后,调用
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

 

2)将我们自已的拦截器注册到注册器中

/**
 * @author zhangboqing
 * @date 2019-07-28
 * 
 * MVC配置类
 */
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {

    /** 创建自定义拦截器实例 */
    @Bean
    MyInterceptor myInterceptor() {
        return new MyInterceptor();
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        //注册自定义拦截器
        registry.addInterceptor(myInterceptor())
                //拦截所有请求
                .addPathPatterns("/*")
                //指定需要过滤的请求地址
//                .excludePathPatterns()
        ;
    }
}

 

三、请求日志记录拦截器实现

import com.alibaba.fastjson.JSON;
import com.talkilla.talkillalexile.common.utils.JodaTimeUtils;
import com.talkilla.talkillalexile.common.utils.RandomCodeUtils;
import com.talkilla.talkillalexile.config.filter.HttpHelperUtils;
import com.talkilla.talkillalexile.config.interceptor.model.PostRequestLogInfoModel;
import com.talkilla.talkillalexile.config.interceptor.model.PreRequestLogInfoModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @author zhangboqing
 * @date 2018/10/13
 * <p>
 * 日志打印拦截
 */
@Slf4j
public class LoggingInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //生成这次请求的唯一标识
        String requestUUID = RandomCodeUtils.getUUID();
        long logStartTime = System.currentTimeMillis();

        //记录开始时间
        request.setAttribute("logStartTime", logStartTime);
        request.setAttribute("requestUUID",requestUUID);

        //请求日志记录
        preRequestLoggin(request,requestUUID);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        long logEndTime = System.currentTimeMillis();
        long logStartTime = (Long)request.getAttribute("logStartTime");
        String requestUUID = (String)request.getAttribute("requestUUID");

        //记录整个请求的执行时间
        loggingHandleTime(requestUUID,logStartTime,logEndTime);
    }

    private void loggingHandleTime(String requestUUID, long logStartTime, long logEndTime) {
        String logInfo = getLoggingHandleTime(requestUUID,logStartTime,logEndTime);
        log.info("[请求拦截日志信息]:{}", logInfo);
    }

    private String getLoggingHandleTime(String requestUUID, long logStartTime, long logEndTime) {
        PostRequestLogInfoModel build = PostRequestLogInfoModel.builder()
                .requestUUID(requestUUID)
                .requestTime(JodaTimeUtils.timestampToString(logStartTime / 1000, JodaTimeUtils.DateFormat.DATETIME_FORMAT))
                .responseTime(JodaTimeUtils.timestampToString(logEndTime / 1000, JodaTimeUtils.DateFormat.DATETIME_FORMAT))
                .handleTime((logEndTime - logStartTime) + "ms").build();

        return JSON.toJSONString(build);
    }

    /**
     * 请求日志记录
     *
     * @param request
     */
    private void preRequestLoggin(HttpServletRequest request,String requestUUID) {
        //获取相关参数
        //请求地址
        String requestURI = request.getRequestURI();
        //请求方法
        String method = request.getMethod();
        //请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        String bodyString = "";
        try {
            bodyString = HttpHelperUtils.getBodyString(request);
        } catch (IOException e) {
            e.printStackTrace();
        }

        String reqestLogInfo = getRequestLogInfo(requestURI, method, parameterMap, bodyString,requestUUID);
        log.info("[请求拦截日志信息]:{}", reqestLogInfo);
    }

    private String getRequestLogInfo(String requestURI, String method, Map<String, String[]> getParameterMap, String postBodyString,String requestUUID) {

        PreRequestLogInfoModel build = PreRequestLogInfoModel.builder()
                .requestUUID(requestUUID)
                .requestURI(requestURI)
                .method(method)
                .getParameter(getParameterMap)
                .postParameter(postBodyString).build();

        return JSON.toJSONString(build);
    }

}
View Code

相关文章: