如何让Swagger生成服务器URL时使用主机名而非IP?
解决Swagger服务器URL自动使用主机名而非IP的问题
核心思路
让Swagger动态读取当前请求的主机名、协议及端口,而非硬编码或默认取服务器IP,这样多环境下无需修改配置,还能避免因IP/主机名不一致导致的CORS问题。
方案1:Spring Boot + Springdoc OpenAPI(主流新版)
通过自定义ServerProvider实现动态服务器URL:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springdoc.core.customizers.ServerProvider; import jakarta.servlet.http.HttpServletRequest; @Configuration public class SwaggerConfig { @Bean public ServerProvider customServerProvider() { return request -> { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes != null) { HttpServletRequest req = attributes.getRequest(); String scheme = req.getScheme(); String host = req.getServerName(); int port = req.getServerPort(); String basePath = req.getContextPath(); // 拼接完整服务器URL String serverUrl = scheme + "://" + host + (port == 80 || port == 443 ? "" : ":" + port) + basePath; return serverUrl; } // fallback到默认逻辑 return null; }; } }
方案2:Spring Boot + Springfox(旧版Swagger 2/3)
配置Docket时动态设置host:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import jakarta.servlet.http.HttpServletRequest; @Configuration public class SwaggerConfig { @Bean public Docket api() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); String host = null; if (attributes != null) { HttpServletRequest req = attributes.getRequest(); String scheme = req.getScheme(); String serverName = req.getServerName(); int port = req.getServerPort(); host = scheme + "://" + serverName + (port == 80 || port == 443 ? "" : ":" + port); } return new Docket(DocumentationType.SWAGGER_2) .host(host) .select() .apis(RequestHandlerSelectors.basePackage("com.your.package")) .paths(PathSelectors.any()) .build(); } }
额外注意事项
- 如果使用Nginx等反向代理,必须配置传递
Host头,否则Swagger无法获取正确的主机名:location / { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; } - 若仍存在CORS问题,需在Spring中配置全局CORS规则,比如:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true); } }
内容的提问来源于stack exchange,提问作者mtmx
相关产品推荐
相关产品推荐

