Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
public abstract class AbstractSwaggerUiConfigProperties {

/**
* The path for the Swagger UI pages to load. Will redirect to the springdoc.webjars.prefix property.
* The path for the Swagger UI pages to load.
*/
protected String path = Constants.DEFAULT_SWAGGER_UI_PATH;

Expand Down Expand Up @@ -814,4 +814,4 @@ public String toString() {
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;

import static org.springdoc.core.utils.Constants.DEFAULT_WEB_JARS_PREFIX_URL;
import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLED;

/**
Expand All @@ -64,11 +63,6 @@ public class SpringDocConfigProperties {
*/
private boolean showActuator;

/**
* The Webjars.
*/
private Webjars webjars = new Webjars();

/**
* The Api docs.
*/
Expand Down Expand Up @@ -786,24 +780,6 @@ public void setShowActuator(boolean showActuator) {
this.showActuator = showActuator;
}

/**
* Gets webjars.
*
* @return the webjars
*/
public Webjars getWebjars() {
return webjars;
}

/**
* Sets webjars.
*
* @param webjars the webjars
*/
public void setWebjars(Webjars webjars) {
this.webjars = webjars;
}

/**
* Gets api docs.
*
Expand Down Expand Up @@ -1390,36 +1366,6 @@ public void setEnabled(boolean enabled) {
}
}

/**
* The type Webjars.
*
* @author bnasslahsen
*/
public static class Webjars {
/**
* The Prefix.
*/
private String prefix = DEFAULT_WEB_JARS_PREFIX_URL;

/**
* Gets prefix.
*
* @return the prefix
*/
public String getPrefix() {
return prefix;
}

/**
* Sets prefix.
*
* @param prefix the prefix
*/
public void setPrefix(String prefix) {
this.prefix = prefix;
}
}

/**
* The type Api docs.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@

package org.springdoc.core.utils;

import org.springframework.util.ResourceUtils;

import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;
import static org.springframework.util.ResourceUtils.CLASSPATH_URL_PREFIX;

/**
* The type Constants.
Expand Down Expand Up @@ -70,7 +69,7 @@ public final class Constants {
/**
* The constant SWAGGER_CONFIG_URL.
*/
public static final String SWAGGER_CONFIG_URL = API_DOCS_URL + DEFAULT_PATH_SEPARATOR + SWAGGER_CONFIG_FILE;
public static final String SWAGGER_CONFIG_URL = API_DOCS_URL + "/" + SWAGGER_CONFIG_FILE;

/**
* The constant YAML.
Expand Down Expand Up @@ -177,21 +176,25 @@ public final class Constants {
*/
public static final String SPRINGDOC_ACTUATOR_DOC_DESCRIPTION = "Spring Boot Actuator Web API Documentation";

/**
* The constant DEFAULT_WEB_JARS_PREFIX_URL.
*/
public static final String DEFAULT_WEB_JARS_PREFIX_URL = "/webjars";
/**
* The constant CLASSPATH_RESOURCE_LOCATION.
*/
public static final String CLASSPATH_RESOURCE_LOCATION = CLASSPATH_URL_PREFIX + "META-INF" + DEFAULT_PATH_SEPARATOR + "resources" + DEFAULT_PATH_SEPARATOR;

/**
* The constant CLASSPATH_RESOURCE_LOCATION.
*/
public static final String CLASSPATH_RESOURCE_LOCATION = ResourceUtils.CLASSPATH_URL_PREFIX + "/META-INF/resources";
/**
* The constant WEBJARS_RESOURCE_LOCATION.
*/
public static final String WEBJARS_RESOURCE_LOCATION = CLASSPATH_RESOURCE_LOCATION + "webjars" + DEFAULT_PATH_SEPARATOR;

/**
* The constant SWAGGER_UI_WEBJAR_NAME.
*/
public static final String SWAGGER_UI_WEBJAR_NAME = "swagger-ui";

/**
* The constant SWAGGER_UI_PREFIX.
*/
public static final String SWAGGER_UI_PREFIX = "/swagger-ui";
public static final String SWAGGER_UI_PREFIX = "/" + SWAGGER_UI_WEBJAR_NAME;

/**
* The constant INDEX_PAGE.
Expand Down Expand Up @@ -231,7 +234,7 @@ public final class Constants {
/**
* The constant DEFAULT_SWAGGER_UI_PATH.
*/
public static final String DEFAULT_SWAGGER_UI_PATH = DEFAULT_PATH_SEPARATOR + "swagger-ui.html";
public static final String DEFAULT_SWAGGER_UI_PATH = "/swagger-ui.html";

/**
* The constant SWAGGER_UI_PATH.
Expand Down Expand Up @@ -363,6 +366,16 @@ public final class Constants {
*/
public static final String ALL_PATTERN = "/**";

/**
* The constant SWAGGER_UI_WEBJAR_NAME_PATTERN.
*/
public static final String SWAGGER_UI_WEBJAR_NAME_PATTERN = "/*" + SWAGGER_UI_WEBJAR_NAME;

/**
* The constant SWAGGER_INITIALIZER_PATTERN.
*/
public static final String SWAGGER_INITIALIZER_PATTERN = "/*" + SWAGGER_INITIALIZER_JS;

/**
* The constant HEALTH_PATTERN.
*/
Expand Down Expand Up @@ -397,7 +410,7 @@ public final class Constants {
/**
* The constant DEFAULT_YAML_API_DOCS_ACTUATOR_PATH.
*/
public static final String DEFAULT_YAML_API_DOCS_ACTUATOR_PATH = DEFAULT_PATH_SEPARATOR + YAML;
public static final String DEFAULT_YAML_API_DOCS_ACTUATOR_PATH = "/" + YAML;

/**
* The constant ACTUATOR_DEFAULT_GROUP.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping;
import org.springframework.boot.webflux.autoconfigure.WebFluxProperties;
import org.springframework.context.annotation.Bean;
Expand Down Expand Up @@ -121,7 +122,8 @@ SwaggerUiHome swaggerUiHome(Optional<WebFluxProperties> optionalWebFluxPropertie
* Swagger web flux configurer swagger web flux configurer.
*
* @param swaggerUiConfigProperties the swagger ui calculated config
* @param springDocConfigProperties the spring doc config properties
* @param springWebProperties the spring web config
* @param springWebFluxProperties the spring webflux config
* @param swaggerIndexTransformer the swagger index transformer
* @param actuatorProvider the actuator provider
* @param swaggerResourceResolver the swagger resource resolver
Expand All @@ -131,9 +133,10 @@ SwaggerUiHome swaggerUiHome(Optional<WebFluxProperties> optionalWebFluxPropertie
@ConditionalOnMissingBean
@Lazy(false)
SwaggerWebFluxConfigurer swaggerWebFluxConfigurer(SwaggerUiConfigProperties swaggerUiConfigProperties,
SpringDocConfigProperties springDocConfigProperties, SwaggerIndexTransformer swaggerIndexTransformer,
Optional<ActuatorProvider> actuatorProvider, SwaggerResourceResolver swaggerResourceResolver) {
return new SwaggerWebFluxConfigurer(swaggerUiConfigProperties, springDocConfigProperties, swaggerIndexTransformer, actuatorProvider, swaggerResourceResolver);
WebProperties springWebProperties, WebFluxProperties springWebFluxProperties,
SwaggerIndexTransformer swaggerIndexTransformer, Optional<ActuatorProvider> actuatorProvider,
SwaggerResourceResolver swaggerResourceResolver) {
return new SwaggerWebFluxConfigurer(swaggerUiConfigProperties, springWebProperties, springWebFluxProperties, swaggerIndexTransformer, actuatorProvider, swaggerResourceResolver);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,21 @@
package org.springdoc.webflux.ui;

import java.util.Optional;

import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springdoc.core.properties.SwaggerUiConfigProperties;
import org.springdoc.core.providers.ActuatorProvider;

import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.webflux.autoconfigure.WebFluxProperties;
import org.springframework.http.CacheControl;
import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;

import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;
import static org.springdoc.core.utils.Constants.ALL_PATTERN;
import static org.springdoc.core.utils.Constants.CLASSPATH_RESOURCE_LOCATION;
import static org.springdoc.core.utils.Constants.DEFAULT_WEB_JARS_PREFIX_URL;
import static org.springdoc.core.utils.Constants.SWAGGER_INITIALIZER_PATTERN;
import static org.springdoc.core.utils.Constants.SWAGGER_UI_PREFIX;
import static org.springdoc.core.utils.Constants.SWAGGER_UI_WEBJAR_NAME;
import static org.springdoc.core.utils.Constants.SWAGGER_UI_WEBJAR_NAME_PATTERN;
import static org.springdoc.core.utils.Constants.WEBJARS_RESOURCE_LOCATION;
import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;

/**
Expand Down Expand Up @@ -69,64 +72,117 @@ public class SwaggerWebFluxConfigurer implements WebFluxConfigurer {
private final SwaggerUiConfigProperties swaggerUiConfigProperties;

/**
* The Spring doc config properties.
* The Spring Web config properties.
*/
private final SpringDocConfigProperties springDocConfigProperties;
private final WebProperties springWebProperties;

/**
* The Spring WebFlux config properties.
*/
private final WebFluxProperties springWebFluxProperties;

private final PathPatternParser parser = new PathPatternParser();

/**
* Instantiates a new Swagger web flux configurer.
*
* @param swaggerUiConfigProperties the swagger ui calculated config
* @param springDocConfigProperties the spring doc config properties
* @param springWebProperties the spring web config
* @param springWebFluxProperties the spring webflux config
* @param swaggerIndexTransformer the swagger index transformer
* @param actuatorProvider the actuator provider
* @param swaggerResourceResolver the swagger resource resolver
*/
public SwaggerWebFluxConfigurer(SwaggerUiConfigProperties swaggerUiConfigProperties,
SpringDocConfigProperties springDocConfigProperties,
SwaggerIndexTransformer swaggerIndexTransformer,
Optional<ActuatorProvider> actuatorProvider, SwaggerResourceResolver swaggerResourceResolver) {
WebProperties springWebProperties, WebFluxProperties springWebFluxProperties,
SwaggerIndexTransformer swaggerIndexTransformer, Optional<ActuatorProvider> actuatorProvider,
SwaggerResourceResolver swaggerResourceResolver) {
this.swaggerIndexTransformer = swaggerIndexTransformer;
this.actuatorProvider = actuatorProvider;
this.swaggerResourceResolver = swaggerResourceResolver;
this.swaggerUiConfigProperties = swaggerUiConfigProperties;
this.springDocConfigProperties = springDocConfigProperties;
this.springWebProperties = springWebProperties;
this.springWebFluxProperties = springWebFluxProperties;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
StringBuilder uiRootPath = new StringBuilder();
String swaggerPath = swaggerUiConfigProperties.getPath();
if (swaggerPath.contains(DEFAULT_PATH_SEPARATOR))
uiRootPath.append(swaggerPath, 0, swaggerPath.lastIndexOf(DEFAULT_PATH_SEPARATOR));
if (actuatorProvider.isPresent() && actuatorProvider.get().isUseManagementPort())
uiRootPath.append(actuatorProvider.get().getBasePath());
String swaggerUiPattern = getUiRootPath() + SWAGGER_UI_PREFIX + ALL_PATTERN;
String swaggerUiResourceLocation = WEBJARS_RESOURCE_LOCATION + SWAGGER_UI_WEBJAR_NAME + DEFAULT_PATH_SEPARATOR +
swaggerUiConfigProperties.getVersion() + DEFAULT_PATH_SEPARATOR;

String webjarsPrefix = springDocConfigProperties.getWebjars().getPrefix();
String resourcePath, swaggerUiPrefix, swaggerUiWebjarsPrefix;
addSwaggerUiResourceHandler(registry, swaggerUiPattern, swaggerUiResourceLocation);

if (DEFAULT_WEB_JARS_PREFIX_URL.equals(webjarsPrefix)) {
swaggerUiPrefix = SWAGGER_UI_PREFIX;
resourcePath = webjarsPrefix + SWAGGER_UI_PREFIX + DEFAULT_PATH_SEPARATOR + swaggerUiConfigProperties.getVersion() + DEFAULT_PATH_SEPARATOR;
swaggerUiWebjarsPrefix = webjarsPrefix + swaggerUiPrefix;
}
else {
swaggerUiPrefix = webjarsPrefix;
resourcePath = DEFAULT_WEB_JARS_PREFIX_URL + DEFAULT_PATH_SEPARATOR;
swaggerUiWebjarsPrefix = swaggerUiPrefix;
// Add custom mappings for Swagger UI WebJar resources if Spring resource mapping is enabled
if (springWebProperties.getResources().isAddMappings()) {
String webjarsPathPattern = springWebFluxProperties.getWebjarsPathPattern();

String swaggerUiWebjarPattern = mergePatterns(webjarsPathPattern, SWAGGER_UI_WEBJAR_NAME_PATTERN) + ALL_PATTERN;
String swaggerUiWebjarResourceLocation = WEBJARS_RESOURCE_LOCATION;

addSwaggerUiResourceHandler(registry, swaggerUiWebjarPattern, swaggerUiWebjarResourceLocation);
}
}

registry.addResourceHandler(uiRootPath + swaggerUiWebjarsPrefix + ALL_PATTERN)
.addResourceLocations(CLASSPATH_RESOURCE_LOCATION + resourcePath)
/**
* Adds the resource handlers for serving the Swagger UI resources.
*/
protected void addSwaggerUiResourceHandler(ResourceHandlerRegistry registry, String pattern, String... resourceLocations) {
registry.addResourceHandler(pattern)
.addResourceLocations(resourceLocations)
.resourceChain(false)
.addResolver(swaggerResourceResolver)
.addTransformer(swaggerIndexTransformer);

registry.addResourceHandler(uiRootPath + swaggerUiPrefix + ALL_PATTERN)
.addResourceLocations(CLASSPATH_RESOURCE_LOCATION + resourcePath)
// Ensure Swagger initializer has "no-store" Cache-Control header
registry.addResourceHandler(mergePatterns(pattern, SWAGGER_INITIALIZER_PATTERN))
.setCacheControl(CacheControl.noStore())
.addResourceLocations(resourceLocations)
.resourceChain(false)
.addResolver(swaggerResourceResolver)
.addTransformer(swaggerIndexTransformer);
}

/**
* Computes and returns the root path for the Swagger UI.
*
* @return the Swagger UI root path.
*/
protected String getUiRootPath() {
StringBuilder uiRootPath = new StringBuilder();

if (actuatorProvider.isPresent() && actuatorProvider.get().isUseManagementPort()) {
uiRootPath.append(actuatorProvider.get().getBasePath());
}

String swaggerUiPath = swaggerUiConfigProperties.getPath();
if (swaggerUiPath.contains(DEFAULT_PATH_SEPARATOR)) {
uiRootPath.append(swaggerUiPath, 0, swaggerUiPath.lastIndexOf(DEFAULT_PATH_SEPARATOR));
}

return uiRootPath.toString();
}

/**
* Combines two patterns into a new pattern according to the rules of {@link PathPattern#combine}.
*
* <p>For example:
* <ul>
* <li><code>/webjars/&#42;&#42;</code> + <code>/swagger-ui/&#42;&#42;</code> => <code>/webjars/swagger-ui/&#42;&#42;</code></li>
* <li><code>/documentation/swagger-ui&#42;/&#42;&#42;</code> + <code>/&#42;.js</code> => <code>/documentation/swagger-ui&#42;/&#42;.js</code></li>
* </ul>
*
* @param pattern1 the first pattern
* @param pattern2 the second pattern
*
* @return the combination of the two patterns
*
* @see PathPattern#combine
*/
private String mergePatterns(String pattern1, String pattern2) {
PathPattern pathPattern1 = parser.parse(parser.initFullPathPattern(pattern1));
PathPattern pathPattern2 = parser.parse(parser.initFullPathPattern(pattern2));

return pathPattern1.combine(pathPattern2).getPatternString();
}
}
Loading