gpt4 book ai didi

spring-boot - 是否可以在与主应用程序不同的端口上运行 SpringFox 的 swagger 和 swagger-ui?

转载 作者:行者123 更新时间:2023-12-02 19:43:33 26 4
gpt4 key购买 nike

我们使用 SpringBoot 和 SpringFox 使用 @EnableSwagger2 来公开 swagger-ui.html API 文档(我们不需要它来自动化客户端代码,就像文档和测试用户界面)。

是否可以在与主应用程序不同的端口(例如 spring boot 管理/监控端口)下运行所有​​与 swagger 相关的端点?

我研究了一下,但没有在 swagger/springfox 的配置中找到一种方法来做到这一点。有没有 Spring 方法可以做到这一点?

最佳答案

是的,有一种 Spring 方法可以做到这一点:

第 1 步。添加额外的 Tomcat 连接器

要向嵌入式服务器添加端口,需要配置额外的连接器。我们将通过提供自定义 WebServerFactoryCustomizer 来实现:

@Component
public class TomcatContainerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

@Value("${swagger.port}")
private int swaggerPort;

@Override
public void customize(TomcatServletWebServerFactory factory) {

Connector swaggerConnector = new Connector();
swaggerConnector.setPort(swaggerPort);
factory.addAdditionalTomcatConnectors(swaggerConnector);
}
}

现在 Tomcat 在两个端口上监听,但它在这两个端口上提供相同的内容。我们需要过滤它。

第 2 步. 添加过滤器

使用 FilterRegistrationBean 添加 servlet 过滤器非常简单。它可以在任何地方创建,我直接将它添加到 TomcatContainerCustomizer。

@Component
public class TomcatContainerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

@Value("${swagger.port}")
private int swaggerPort;

@Value("${swagger.paths}")
private List<String> swaggerPaths;

@Override
public void customize(TomcatServletWebServerFactory factory) {

Connector swaggerConnector = new Connector();
swaggerConnector.setPort(swaggerPort);
factory.addAdditionalTomcatConnectors(swaggerConnector);
}

@Bean
public FilterRegistrationBean<SwaggerFilter> swaggerFilterRegistrationBean() {

FilterRegistrationBean<SwaggerFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new SwaggerFilter());
filterRegistrationBean.setOrder(-100);
filterRegistrationBean.setName("SwaggerFilter");

return filterRegistrationBean;
}

private class SwaggerFilter extends OncePerRequestFilter {

private AntPathMatcher pathMatcher = new AntPathMatcher();

@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
FilterChain filterChain) throws ServletException, IOException {

boolean isSwaggerPath = swaggerPaths.stream()
.anyMatch(path -> pathMatcher.match(path, httpServletRequest.getServletPath()));
boolean isSwaggerPort = httpServletRequest.getLocalPort() == swaggerPort;

if(isSwaggerPath == isSwaggerPort) {
filterChain.doFilter(httpServletRequest, httpServletResponse);
} else {
httpServletResponse.sendError(404);
}
}
}
}

属性 swagger.portswagger.paths 在 application.yaml 中配置:

server.port: 8080
swagger:
port: 8088
paths: |
/swagger-ui.html,
/webjars/springfox-swagger-ui/**/*,
/swagger-resources,
/swagger-resources/**/*,
/v2/api-docs

到目前为止一切顺利:swagger-ui 在端口 8088 上提供服务,我们的 api 在 8080 上提供服务。但是有一个问题:当我们尝试从 swagger-ui 连接到 api 时,请求被发送到 8088 而不是 8080。

第 3 步. 调整 SpringFox 配置。

Swagger 假定 api 在与 swagger-ui 相同的端口上运行。我们需要明确指定端口:

@Value("${server.port}")
private int serverPort;

@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.host("localhost:" + serverPort);
}

最后一个问题:由于 ui 运行在与 api 不同的端口上,这些请求被认为是跨源的。我们需要解锁它们。它可以在全局范围内完成:

@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**/*").allowedOrigins("http://localhost:" + swaggerPort);
}
};
}

或者通过向 Controller 添加注解:

@CrossOrigin(origins = "http://localhost:${swagger.port}")

使用的版本:SpringBoot 2.2.2.RELEASE, springfox-swagger2 2.9.2

有关工作示例,请参阅 https://github.com/mafor/swagger-ui-port

关于spring-boot - 是否可以在与主应用程序不同的端口上运行 SpringFox 的 swagger 和 swagger-ui?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59748041/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com