I also have faced this problem and tried many possible resolutions, and nothings didn't help really.
In my case, I can't use any resource redirect as swagger must be accessible as locally as on google cloud by match path /api-docs/**. and on google cloud any resource redirection will be denied in my case. All resources must be loading also from this path
here is my solution:
springfox-swagger2 and springfox-swagger-ui of version 2.9.2
@EnableSwagger2
@Configuration
public class SwaggerCommonConfig implements WebMvcConfigurer {
public static final String PATH = "/api-docs";
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController(PATH, "/");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(PATH + "/**").addResourceLocations("classpath:/META-INF/resources/");
}
}
and as springfox don't have any possibilities to do it by another way, in my case, we just will create simple controller that will be translating resource requests from our custom path to standard springfox. (it's not very elegant part but as it is :))
@RestController
@RequestMapping(SwaggerGatewayCommonConfig.PATH)
@RequiredArgsConstructor
public class SwaggerController {
private final RestTemplate restTemplate;
private final static String V2_API_DOCS = "/v2/api-docs";
private final static String SWAGGER_RESOURCES_CONFIGURATION_UI = "/swagger-resources/configuration/ui";
private final static String SWAGGER_RESOURCES_CONFIGURATION_SECURITY = "/swagger-resources/configuration/security";
private final static String SWAGGER_RESOURCES = "/swagger-resources";
private final static Pattern pattern = Pattern.compile("http[s]*://([^/]+)", Pattern.CASE_INSENSITIVE);
@Value("${server.port}")
private String port;
@GetMapping(V2_API_DOCS)
@SuppressWarnings("unchecked")
public Map<String, Object> getV2ApiDocs(HttpServletRequest request) {
Matcher matcher = pattern.matcher(request.getRequestURL().toString());
matcher.find();
Map<String, Object> resp = (Map<String, Object>) restTemplate.getForObject(toLocalSwaggerUrl(V2_API_DOCS), Map.class);
//we have to replace standard host, to requested host. as swagger UI make api requests from this host
resp.put("host", matcher.group(1));
return resp;
}
@GetMapping(SWAGGER_RESOURCES_CONFIGURATION_UI)
public Object getSwaggerResourcesConfigurationUi() {
return restTemplate.getForObject(toLocalSwaggerUrl(SWAGGER_RESOURCES_CONFIGURATION_UI), Object.class);
}
@GetMapping(SWAGGER_RESOURCES_CONFIGURATION_SECURITY)
public Object getSwaggerResourcesConfigurationSecurity() {
return restTemplate.getForObject(toLocalSwaggerUrl(SWAGGER_RESOURCES_CONFIGURATION_SECURITY), Object.class);
}
@GetMapping(SWAGGER_RESOURCES)
public Object getSwaggerResources() {
return restTemplate.getForObject(toLocalSwaggerUrl(SWAGGER_RESOURCES), Object.class);
}
private String toLocalSwaggerUrl(String path) {
return "http://localhost:" + port + path;
}
}
I hope it will save time to somebody faced it also =)
Good luck