springboot中使用拦截器进行拦截请求处理

应用场景
项目中要拦截指定url之外的所有请求,并在请求进入controller之前判断其中的参数是否合法正确.

  1. 注册拦截器:继承 WebMvcConfigurationSupport ,重写 addInterceptors 方法
@Configuration public class InterceptorConfig extends WebMvcConfigurationSupport {private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private JumpControllerInterceptor jumpControllerInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { # 这里添加的路径不包含项目的contextPath哦 registry.addInterceptor(jumpControllerInterceptor).addPathPatterns("/**"). excludePathPatterns("/test"); super.addInterceptors(registry); }@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String os = System.getProperty("os.name"); //如果是Windows系统 //if (os.toLowerCase().startsWith("win")) { //registry.addResourceHandler("/app_file/**") //// /app_file/**表示在磁盘filePathWindow目录下的所有资源会被解析为以下的路径 //.addResourceLocations("file:" + filePathWindow); //} else {//linux 和mac //registry.addResourceHandler("/app_file/**") //.addResourceLocations("file:" + filePathLinux) ; //}registry.addResourceHandler("/jumpLogs/**").addResourceLocations("file:jumpLogs/"); super.addResourceHandlers(registry); } }

  1. 实现HandlerInterceptor这个接口
    @Component public class JumpControllerInterceptor implements HandlerInterceptor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object o) { String requestURI = req.getRequestURI(); if(requestURI.startsWith("/jump/app/")){ logger.info("正在检查pathVariable: appCode"); Map pathVariables = (Map) req.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); String appCode = (String)pathVariables.get("appCode"); /* 2.判断是否IDP登录 */ AppAddrMapping appAddrMapping = AppAddrMapping.ADDR_MAPPING_MAP.get(appCode); if (null == appAddrMapping) { logger.error("当前url中的appCode : {} 和app.json中的不相匹配,请检查配置文件",appCode); throw new ConfArgException("app不存在,请检查appcode是否正确"); } } return true; } @Override public void postHandle(HttpServletRequest req, HttpServletResponse res, Object o, ModelAndView mav) { } @Override public void afterCompletion(HttpServletRequest req, HttpServletResponse rep, Object o, Exception e) { }

  2. 拦截器不起作用的原因
    a) 继承 WebMvcConfigurationSupport ,重写 addInterceptors 方法的类需用到@Configuration 注解
    b) addPathPatterns中的问题。拦截器最后路径一定要 /, 如果是目录的话则是 /*/
    c) excludePathPatterns 或 addPathPatterns 书写错误,前面添加了项目的ContextPath
  3. 拦截器的主要方法
    configurePathMatch:配置路由请求规则 configureContentNegotiation:内容协商配置 configureAsyncSupport configureDefaultServletHandling:默认静态资源处理器 addFormatters:注册自定义转化器 addInterceptors:拦截器配置 addResourceHandlers:资源处理 addCorsMappings:CORS配置 addViewControllers:视图跳转控制器 configureViewResolvers:配置视图解析 addArgumentResolvers:添加自定义方法参数处理器 addReturnValueHandlers:添加自定义返回结果处理器 configureMessageConverters:配置消息转换器。重载会覆盖默认注册的HttpMessageConverter extendMessageConverters:配置消息转换器。仅添加一个自定义的HttpMessageConverter. configureHandlerExceptionResolvers:配置异常转换器 extendHandlerExceptionResolvers:添加异常转化器 getValidator getMessageCodesResolver

  4. 其中用的比较多的是一下三个接口:
/** 解决跨域问题 **/ public void addCorsMappings(CorsRegistry registry) ; /** 添加拦截器 **/ void addInterceptors(InterceptorRegistry registry); /** 静态资源处理 **/ void addResourceHandlers(ResourceHandlerRegistry registry);

@Configuration public class AddCorsMappings extends WebMvcConfigurationSupport { /** * 跨域访问配置接口 * @param registry */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") .allowCredentials(true) .allowedHeaders("*") .maxAge(3600); } }

【springboot中使用拦截器进行拦截请求处理】关于静态资源的处理
非常重要的提示:Springboot中只能有一个WebMvcConfigurationSupport配置类是真正起作用的,对于这个问题,其实可以通过implements WebMvcConfigurer来解决,多个不同的类实现这个接口后的配置都可以正常运行。
关于用Servlet获取URL地址。
在HttpServletRequest类里,有以下六个取URL的函数
getContextPath 取得项目名
getServletPath 取得Servlet名
getPathInfo 取得Servlet后的URL名,不包括URL参数
getRequestURL 取得不包括参数的URL
getRequestURI 取得不包括参数的URI,即去掉协议和服务器名的URL
具体如下图:
springboot中使用拦截器进行拦截请求处理
文章图片

相对应的函数的值如下:
getContextPath:/ServletTest
getServletPath:/main
getPathInfo:/index/testpage/test
getRequestURL:http://localhost:8080/Servlet...
getRequestURI:/ServletTest/main/index/testpage/test

    推荐阅读