Spring Boot根路径RequestMapping如何排除静态文件目录?
解决@RequestMapping("/**")覆盖Swagger静态资源的方案
由于无法修改现有@RequestMapping(value = "/**", method = RequestMethod.GET)配置,以下是几种无需改动该注解即可排除swagger目录的可行方案:
方法1:新增精确匹配的Swagger资源映射Controller
利用Spring MVC精确路径优先匹配的规则,新增一个专门处理swagger路径的Controller,让它优先接管/swagger/开头的请求:
@RestController public class SwaggerStaticController { @GetMapping("/swagger/**") public ResponseEntity<Resource> serveSwaggerFiles(HttpServletRequest request) { // 截取swagger路径后的部分,定位到静态资源 String resourcePath = request.getRequestURI().replaceFirst("^/swagger/", ""); Resource targetResource = new ClassPathResource("static/swagger/" + resourcePath); if (targetResource.exists() && targetResource.isReadable()) { return ResponseEntity.ok(targetResource); } return ResponseEntity.notFound().build(); } }
方法2:通过WebMvcConfigurer调整路径匹配规则
自定义路径匹配逻辑,让通用的/**映射跳过swagger相关路径,同时提升静态资源处理器的优先级:
@Configuration public class CustomWebMvcConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { AntPathMatcher defaultMatcher = new AntPathMatcher(); configurer.setPathMatcher(new PathMatcher() { @Override public boolean match(String pattern, String path) { // 若请求路径以/swagger/开头,直接返回不匹配通用的/** if (path.startsWith("/swagger/")) { return false; } return defaultMatcher.match(pattern, path); } // 其余方法直接委托给默认的AntPathMatcher @Override public String combine(String pattern1, String pattern2) { return defaultMatcher.combine(pattern1, pattern2); } @Override public String extractPathWithinPattern(String pattern, String path) { return defaultMatcher.extractPathWithinPattern(pattern, path); } @Override public Map<String, String> extractUriTemplateVariables(String pattern, String path) { return defaultMatcher.extractUriTemplateVariables(pattern, path); } @Override public boolean isPattern(String path) { return defaultMatcher.isPattern(path); } @Override public Comparator<String> getPatternComparator(String path) { return defaultMatcher.getPatternComparator(path); } @Override public String[] getPatternsByUriTemplate(String uriTemplate) { return defaultMatcher.getPatternsByUriTemplate(uriTemplate); } }); } // 显式配置swagger静态资源的映射规则 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/swagger/**") .addResourceLocations("classpath:/static/swagger/") .setCachePeriod(0); } }
方法3:用HandlerInterceptor拦截并放行Swagger请求
实现拦截器,当检测到swagger路径请求时,直接转发到静态资源,跳过通用Controller的处理:
@Component public class SwaggerExcludeInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestUri = request.getRequestURI(); if (requestUri.startsWith("/swagger/")) { // 转发到对应的静态资源文件 String resourcePath = requestUri.substring("/swagger/".length()); request.getRequestDispatcher("/static/swagger/" + resourcePath).forward(request, response); return false; // 阻止后续通用Controller处理该请求 } return true; } }
然后在WebMvc配置中注册该拦截器:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired private SwaggerExcludeInterceptor swaggerExcludeInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(swaggerExcludeInterceptor) .addPathPatterns("/**"); } }
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

