springfox-swagger-ui Nginx 404问题

前言

本文解决 springfox-swagger-ui 在二级目录下的使用问题。如同一个域名的 /user 和 /post 用 Nginx 分别反向代理指向不同的应用,我们希望在每个应用中都可以正常使用 Swagger。

下面,我们假设要配置 /user 指向 user 应用。

很多人爱折腾,会打起修改源码的主意,希望本文能帮你节省点时间。

注意:本文使用的 springfox-swagger2 版本是 2.9.2

解决方法 - 1

修改全局 context path

Spring Boot 环境中只要配置以下环境变量即可:

server.contextPath=/user

那么你的所有的接口,默认就都是在 /user 下面了,自然 swagger-ui 也就能正常使用了,访问 /user/swagger-ui.html 即可。

这是最最简单的方法,不过在有些特定的环境中会有问题,比如我司:

由于设置了 contextPath,那么健康检测接口 /health 也会被自动换为 /user/health,而我们的发布系统一根筋地要找 /health 接口,也就导致我们的应用会发布不了。

只有在碰到这种方法解决不了的时候,我们才要考虑使用下面介绍的方法。

解决方法 - 2

使用 Controller 做 forward

首先,将 /user/swagger-ui.html forward 到 /swagger-ui.html。

1
2
3
4
@GetMapping("/swagger-ui.html")
public String index() {
return "forward:/swagger-ui.html";
}

剩下的其实很简单,大家打开 your-domain/user/swagger-ui.html 页面,发现可以看到 swagger-ui 页面,但是接口列表没出来。

然后打开浏览器控制台,就会发现,它有很多发向 /user/webjars/… 和 /user/swagger… 的请求都是 404,我们只要一一把这些请求搞定就 OK 了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
@Controller
// 看这里
@RequestMapping("user")
public class SwaggerController extends BaseController {

@GetMapping("/swagger-ui.html")
public String index() {
return "forward:/swagger-ui.html";
}

@GetMapping("/webjars/springfox-swagger-ui/css/{s:.+}")
public String css(@PathVariable String s) {
return "forward:/webjars/springfox-swagger-ui/css/" + s;
}

@GetMapping("/webjars/springfox-swagger-ui/{s:.+}")
public String baseJs(@PathVariable String s) {
return "forward:/webjars/springfox-swagger-ui/" + s;
}

@GetMapping("/webjars/springfox-swagger-ui/lib/{s:.+}")
public String js(@PathVariable String s) {
return "forward:/webjars/springfox-swagger-ui/lib/" + s;
}

@GetMapping("/webjars/springfox-swagger-ui/images/{s:.+}")
public String images(@PathVariable String s) {
return "forward:/webjars/springfox-swagger-ui/images/" + s;
}

@GetMapping("/swagger-resources/configuration/ui")
public String ui() {
return "forward:/swagger-resources/configuration/ui";
}

@GetMapping("/swagger-resources")
public String resources() {
return "forward:/swagger-resources";
}

@GetMapping("/v2/api-docs")
public String docs() {
return "forward:/v2/api-docs";
}

@GetMapping("/swagger-resources/configuration/security")
public String security() {
return "forward:/swagger-resources/configuration/security";
}
}

解决方法 - 3

使用 ViewControllerRegistry

参考百度其他人的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/user/**").addResourceLocations("classpath:/META-INF/resources/");
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/user/v2/api-docs", "/v2/api-docs").setKeepQueryParams(true);
registry.addRedirectViewController("/user/swagger-resources/configuration/ui","/swagger-resources/configuration/ui");
registry.addRedirectViewController("/user/swagger-resources/configuration/security","/swagger-resources/configuration/security");
registry.addRedirectViewController("/user/swagger-resources", "/swagger-resources");
}
}

这种写法,访问静态资源的时候是完全没有问题的,但是 swagger-ui.html 页面在使用 ajax 调用接口的时候,这种配置做的是跳转,如 “/user/v2/api-docs” 自动跳转到 “/v2/api-docs” 其实是不满足我们需求的,因为 /v2/api-docs 这个路径根本就不会跳到我们的 user 应用。

解决方法 - 4

NGINX 端处理

将项目打成 war,项目名不用 ROOT,用二级路径名也是可行的,注意 nginx 端 conf 配置不要 expires 以下静态资源  location ~* .(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { … }

作者

Catooilg

发布于

2020-08-04

更新于

2025-02-10

许可协议

评论