拦截器实现

103 阅读2分钟

下面所有用到的代码基于项目云图

Interceptor 应用场景 拦截器本质上是面向切面编程(AOP),符合横切关注点的功能都可以放在拦截器中来实现。

日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算 PV(Page View)等。 权限检查:判断用户是否有权限访问资源,如校验token。 性能监控:通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间。(反向代理,如 Apache 也可以自动记录) 通用行为:读取 Cookie 得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取 Locale、Theme 信息等,只要是多个处理器都需要的即可使用拦截器实现。 登录验证:判断用户是否登录。 其他:处理cookie、本地化、国际化、主题等。

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport{
   
   @Bean
    public AuthorizationInterceptor getAuthorizationInterceptor() {
        return new AuthorizationInterceptor();
    }
   
   @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getAuthorizationInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");
        super.addInterceptors(registry);
   }
   
   /**
    * springboot 2.0配置WebMvcConfigurationSupport之后,会导致默认配置被覆盖,要访问静态资源需要重写addResourceHandlers方法
    */
   @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
      registry.addResourceHandler("/**")//指定了要处理的URL路径。在这里,它表示处理所有的URL路径。
        .addResourceLocations("classpath:/resources/")
        .addResourceLocations("classpath:/static/")
        .addResourceLocations("classpath:/admin/")
        .addResourceLocations("classpath:/front/")
        .addResourceLocations("classpath:/public/");
      super.addResourceHandlers(registry);

      //这段代码的作用是将这些URL路径映射到对应的静态资源目录,以便浏览器可以访问这些静态资源文件。例如,如果你有一个名为style.css的样式文件,可以通过/static/style.css访问它。
    }
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {

    public static final String LOGIN_TOKEN_KEY = "Token";


   @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

      //支持跨域请求
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,request-source,Token, Origin,imgType, Content-Type, cache-control,postman-token,Cookie, Accept,authorization");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
   // 跨域时会首先发送一个OPTIONS请求,这里我们给OPTIONS请求直接返回正常状态
   if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
           response.setStatus(HttpStatus.OK.value());
            return false;
        }
        
        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            return true;
        }

        //从header中获取token
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        
        */
/**
         * 不需要验证权限的方法直接放过
         *//*

        if(annotation!=null) {
           return true;
        }
        
        TokenEntity tokenEntity = null;
        if(StringUtils.isNotBlank(token)) {
           tokenEntity = tokenService.getTokenEntity(token);
        }
        
        if(tokenEntity != null) {
           request.getSession().setAttribute("userId", tokenEntity.getUserid());
           request.getSession().setAttribute("role", tokenEntity.getRole());
           request.getSession().setAttribute("tableName", tokenEntity.getTablename());
           request.getSession().setAttribute("username", tokenEntity.getUsername());
           return true;
        }
        return true;
      */
/*PrintWriter writer = null;
      response.setCharacterEncoding("UTF-8");
      response.setContentType("application/json; charset=utf-8");
      try {
          writer = response.getWriter();
          writer.print(JSONObject.toJSONString(R.error(401, "请先登录")));
      } finally {
          if(writer != null){
              writer.close();
          }
      }
//          throw new EIException("请先登录", 401);
      return false;*//*

    }
}

参考文章