zoukankan      html  css  js  c++  java
  • Spring Boot拦截器实现并和swagger集成后使用拦截器的配置问题

    1. 定义拦截器 LoginInterceptor

    LoginInterceptor.java是整个登录认证模块中的核心类之一,它实现了HandlerInterceptor类,由它来拦截并过滤到来的每一个请求;它的三个方法能分别作用于每个请求的不同生命周期,你可以根据自己的需要来加入相应的处理逻辑

    package com.demo.common.interceptor;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.TypeReference;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    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.BufferedReader;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.io.Reader;
    import java.io.StringWriter;
    import java.io.Writer;
    import java.lang.reflect.Type;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @ProjectName: demo
     * @Package: com.demo.common.interceptor
     * @ClassName: LoginInterceptor
     * @Description: 登录请求拦截器
     * @Author:
     * @Date: 
     * @Version: 1.0
     */
    @Slf4j
    public class LoginInterceptor implements HandlerInterceptor {
    
      /**
       * 在请求被处理之前调用
       * @param request
       * @param response
       * @param handler
       * @return
       * @throws Exception
       */
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
        String requestMethod = request.getMethod();
        if (requestMethod.contains("OPTIONS") || requestMethod.contains("options")) {
          return true;
        }
    
        //token 校验
        String token = request.getHeader("token");
        if (StringUtil.isEmpty(token)) {
          token = request.getHeader("token-inc");
        }
    
        //获取请求页面id
        String pageId = "";
        Map<String, String[]> paramMap = request.getParameterMap();
        if (CollectionUtils.isNotEmpty(paramMap)) {
          if (paramMap.containsKey("page_id")) {
            pageId = paramMap.get("page_id")[0];
          }
        }
    
        //验证token是否有效
        boolean checkToken = this.checkToken(token, pageId);
        if (!checkToken) {
          //未登录就跳转到登录页面
          //response.sendRedirect(LOGIN_HOST + "login");
          Result<String> resultObject = Result.fail("10001", "登录超时,请刷新页面重新登录");
          PrintWriter writer = response.getWriter();
          writer.write(JSON.toJSONString(resultObject));
          writer.flush();
          writer.close();
          return false;
        }
    
        //参数日志打印
        if (handler instanceof HandlerMethod) {
          this.saveRequestLog(request);
        }
        return true;
      }
    
      /**
       * 在请求被处理后,视图渲染之前调用
       * @param request
       * @param response
       * @param handler
       * @param modelAndView
       * @throws Exception
       */
      @Override
      public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //Collection<String> headerNames = response.getHeaderNames();
        //log.info("[postHandle]{}", JsonUtils.toJson(headerNames));
      }
    
      /**
       * 在整个请求结束后调用
       * @param request
       * @param response
       * @param handler
       * @param ex
       * @throws Exception
       */
      @Override
      public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserInfoHolder.removeUserInfo();
      }
    
      /**
       * 请求校验token 塞入ThreadLocal
       *
       * @param token
       * @return
       */
      private boolean checkToken(String token, String pageId) {
        //不需要验证,直接通过,使用于直接请求接口(测试用)
        if ("false".equals(ENABLE_TOKEN) || NOT_VAILE_TOKEN.equals(token)) {
          return true;
        }
    
        if (StringUtil.isEmpty(token)) {
          return false;
        }
    
        //请求获取登录用户信息及权限
        HttpBO<UserInfoBO> httpBO = this.httpUserInfo(token, pageId);
    
        if (httpBO == null || httpBO.getCode() == null || httpBO.getCode() != 0 || httpBO.getData() == null) {
          return false;
        }
    
        this.saveLoginContext(httpBO.getData());
    
        return true;
      }
    
      private HttpBO<UserInfoBO> httpUserInfo(String token, String pageId) {
        HttpBO<UserInfoBO> httpBO = new HttpBO<>();
        try {
          LoginQuery loginQuery = new LoginQuery();
          loginQuery.setCookieStr(token);
          loginQuery.setPageId(pageId);
          String url = API_HOST + USER_URL;
          String jsonUserInfoBo = JSON.toJSONString(loginQuery);
          log.info("发送请求获取权限参数信息 param:{},url:{}", jsonUserInfoBo, url);
          String response = HttpClientPostUtil.sendPostRequest(url, jsonUserInfoBo);
          log.info("发送请求获取权限返回信息 response={}", response);
          Type type = new TypeReference<HttpBO<UserInfoBO>>() {
          }.getType();
          httpBO = JSON.parseObject(response, type);
          //httpBO = JSON.parseObject(response, new HttpBO<UserInfoBO>().getClass());
          log.info("发送请求获取权限信息 封装 httpBO:{}", JSON.toJSONString(httpBO));     
        } catch (Exception ex) {
          log.error("发送请求获取权限失败 error:{}", ex.getMessage());     
        }
        return httpBO;
      }
    
      private void saveLoginContext(UserInfoBO userInfoBO) {
        //List<ButtonBO> buttonBOList = userInfoBO.getUserBtns();
        //if (CollectionUtils.isEmpty(buttonBOList)) {
        //  List<String> code = buttonBOList.stream().map(ButtonBO::getBtnCode).collect(Collectors.toList());
        //}
    
        UserInfoHolder.setUserInfo(userInfoBO);
      }
    
      private void saveRequestLog(HttpServletRequest request) throws Exception {
        StringBuilder builder = new StringBuilder();
        builder.append("请求入口 ");
        builder.append("PATH => ");
        builder.append(request.getRequestURI());
        builder.append(",METHOD => ");
        builder.append(request.getMethod());
        builder.append(",PARAM => ");
        Map<String, String[]> paramMap = request.getParameterMap();
        if (CollectionUtils.isNotEmpty(paramMap)) {
          builder.append(JSON.toJSONString(paramMap));
          builder.append(",page_id => ");
          if (paramMap.containsKey("page_id")) {
            builder.append(paramMap.get("page_id")[0]);
          }
          log.info(builder.toString());
          return;
        }
        if (request instanceof MultipartHttpServletRequest) {
          log.info(builder.toString());
          return;
        }
        //由于request.getReader流只能操作一次,这里用过一次后,在Control中获取RequestBody中参数就获取不到,所以这里要先注释掉,后续解决
    //    BufferedReader reader = request.getReader();
    //    String body = this.read(reader);
    //    if (StringUtil.isNotEmpty(body)) {
    //      body = body.replace("
    ", "");
    //    }
    //    builder.append(body);
        log.info(builder.toString());
      }
    
      private String read(Reader reader) throws IOException {
        StringWriter writer = new StringWriter();
        try {
          this.write(reader, writer, 1024 * 8);
          return writer.getBuffer().toString();
        } finally {
          writer.close();
        }
      }
    
      private long write(Reader reader, Writer writer, int bufferSize) throws IOException {
        int read;
        long total = 0;
        char[] buf = new char[bufferSize];
        while ((read = reader.read(buf)) != -1) {
          writer.write(buf, 0, read);
          total += read;
        }
        return total;
      }
    
    }
    View Code

    2. 注册拦截器配置 LoginConfiguration

    LoginConfiguration.java是另一个核心类之一,它继承自WebMvcConfigurer类,负责注册并生效我们自己定义的拦截器配置;在这里要注意定义好拦截路径和排除拦截的路径;

    package com.demo.common.configuration;
    
    import com.demo.common.interceptor.LoginInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    import org.springframework.web.servlet.handler.MappedInterceptor;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @ProjectName: demo
     * @Package: com.demo.common.configuration
     * @ClassName: LoginConfiguration
     * @Description: 负责注册并生效自己定义的拦截器配置
     * @Author:
     * @Date: 
     * @Version: 1.0
     */
    @Configuration
    public class LoginConfiguration implements WebMvcConfigurer {
      @Bean
      public MappedInterceptor getMappedInterceptor() {
        //注册拦截器
        LoginInterceptor loginInterceptor = new LoginInterceptor();
        //拦截路径 ("/**")对所有请求都拦截
        String[] includePatterns = new String[]{"/**"};
        //排除拦截路径
        String[] excludePatterns = new String[]{"/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**",
          "/api", "/api-docs", "/api-docs/**"};
    
        //将数组转化为集合
        List<String> listOldExclude = Arrays.asList(excludePatterns);
    
        //将自定义的排除拦截路径添加到集合中
        List<String> listNewExclude = new ArrayList<>();
        listNewExclude.add("/demoJson/getCityList.json");
        listNewExclude.add("/demoJson/getStudentList.json");
        
        //定义新集合
        List<String> listExclude = new ArrayList<>();
        listExclude.addAll(listOldExclude);
        listExclude.addAll(listNewExclude);
    
        //将新集合转化回新数组
        String[] newExcludePatterns = listExclude.toArray(new String[listExclude.size()]);
    
        return new MappedInterceptor(includePatterns, newExcludePatterns, loginInterceptor);
      }
    }
    View Code
  • 相关阅读:
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第一题
    fiddler模拟发送post请求
  • 原文地址:https://www.cnblogs.com/li150dan/p/12072023.html
Copyright © 2011-2022 走看看