From 2e6019c5a776649cf1c598bc5587257469cd35fe Mon Sep 17 00:00:00 2001 From: cbornet Date: Fri, 18 May 2018 13:35:26 +0200 Subject: [PATCH] Do not set contextPath for spring-boot --- .../codegen/languages/SpringCodegen.java | 43 ++++++------------- .../JavaSpring/apiController.mustache | 6 +++ .../resources/JavaSpring/application.mustache | 1 - .../libraries/spring-boot/README.mustache | 2 +- .../spring-boot/defaultBasePath.mustache | 1 + .../spring-mvc/defaultBasePath.mustache | 1 + .../openapiUiConfiguration.mustache | 2 +- .../openapiDocumentationConfig.mustache | 33 +++++++++++++- .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../OpenAPIDocumentationConfig.java | 30 ++++++++++++- .../configuration/OpenAPIUiConfiguration.java | 2 +- .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../OpenAPIDocumentationConfig.java | 30 ++++++++++++- .../configuration/OpenAPIUiConfiguration.java | 2 +- .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../OpenAPIDocumentationConfig.java | 30 ++++++++++++- .../configuration/OpenAPIUiConfiguration.java | 2 +- .../configuration/SwaggerUiConfiguration.java | 2 +- .../springboot-beanvalidation/README.md | 3 ++ .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../OpenAPIDocumentationConfig.java | 30 ++++++++++++- .../src/main/resources/application.properties | 1 - .../petstore/springboot-delegate-j8/README.md | 3 ++ .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../OpenAPIDocumentationConfig.java | 30 ++++++++++++- .../src/main/resources/application.properties | 1 - .../petstore/springboot-delegate/README.md | 3 ++ .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../OpenAPIDocumentationConfig.java | 30 ++++++++++++- .../src/main/resources/application.properties | 1 - .../springboot-implicitHeaders/README.md | 3 ++ .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../OpenAPIDocumentationConfig.java | 30 ++++++++++++- .../src/main/resources/application.properties | 1 - .../petstore/springboot-reactive/README.md | 3 -- .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../src/main/resources/application.properties | 1 - .../petstore/springboot-useoptional/README.md | 3 ++ .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../OpenAPIDocumentationConfig.java | 29 ++++++++++++- .../src/main/resources/application.properties | 1 - samples/server/petstore/springboot/README.md | 3 ++ .../api/AnotherFakeApiController.java | 2 + .../openapitools/api/FakeApiController.java | 2 + .../api/FakeClassnameTestApiController.java | 2 + .../openapitools/api/PetApiController.java | 2 + .../openapitools/api/StoreApiController.java | 2 + .../openapitools/api/UserApiController.java | 2 + .../OpenAPIDocumentationConfig.java | 30 ++++++++++++- .../src/main/resources/application.properties | 1 - 95 files changed, 457 insertions(+), 57 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/defaultBasePath.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-mvc/defaultBasePath.mustache diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index 58be3e693777..4a991727756f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -18,7 +18,6 @@ package org.openapitools.codegen.languages; import com.samskivert.mustache.Mustache; -import com.samskivert.mustache.Template; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; @@ -41,8 +40,6 @@ import org.slf4j.LoggerFactory; import java.io.File; -import java.io.IOException; -import java.io.Writer; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -71,7 +68,7 @@ public class SpringCodegen extends AbstractJavaCodegen public static final String SPRING_BOOT = "spring-boot"; public static final String SPRING_CLOUD_LIBRARY = "spring-cloud"; public static final String IMPLICIT_HEADERS = "implicitHeaders"; - public static final String SWAGGER_DOCKET_CONFIG = "swaggerDocketConfig"; + public static final String OPENAPI_DOCKET_CONFIG = "swaggerDocketConfig"; protected String title = "OpenAPI Spring"; protected String configPackage = "org.openapitools.configuration"; @@ -87,7 +84,7 @@ public class SpringCodegen extends AbstractJavaCodegen protected boolean useTags = false; protected boolean useBeanValidation = true; protected boolean implicitHeaders = false; - protected boolean swaggerDocketConfig = false; + protected boolean openapiDocketConfig = false; protected boolean useOptional = false; public SpringCodegen() { @@ -116,7 +113,7 @@ public SpringCodegen() { cliOptions.add(CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames")); cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations")); cliOptions.add(CliOption.newBoolean(IMPLICIT_HEADERS, "Use of @ApiImplicitParams for headers.")); - cliOptions.add(CliOption.newBoolean(SWAGGER_DOCKET_CONFIG, "Generate Spring Swagger Docket configuration class.")); + cliOptions.add(CliOption.newBoolean(OPENAPI_DOCKET_CONFIG, "Generate Spring OpenAPI Docket configuration class.")); cliOptions.add(CliOption.newBoolean(USE_OPTIONAL, "Use Optional container for optional parameters")); @@ -235,8 +232,8 @@ public void processOpts() { this.setImplicitHeaders(Boolean.valueOf(additionalProperties.get(IMPLICIT_HEADERS).toString())); } - if (additionalProperties.containsKey(SWAGGER_DOCKET_CONFIG)) { - this.setSwaggerDocketConfig(Boolean.valueOf(additionalProperties.get(SWAGGER_DOCKET_CONFIG).toString())); + if (additionalProperties.containsKey(OPENAPI_DOCKET_CONFIG)) { + this.setOpenapiDocketConfig(Boolean.valueOf(additionalProperties.get(OPENAPI_DOCKET_CONFIG).toString())); } typeMapping.put("file", "Resource"); @@ -283,7 +280,7 @@ public void processOpts() { supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache", (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "RFC3339DateFormat.java")); supportingFiles.add(new SupportingFile("application.properties", - ("src.main.resources").replace(".", java.io.File.separator), "swagger.properties")); + ("src.main.resources").replace(".", java.io.File.separator), "openapi.properties")); } if (library.equals(SPRING_CLOUD_LIBRARY)) { supportingFiles.add(new SupportingFile("apiKeyRequestInterceptor.mustache", @@ -310,7 +307,7 @@ public void processOpts() { (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "OpenAPIDocumentationConfig.java")); } } - } else if (this.swaggerDocketConfig && !library.equals(SPRING_CLOUD_LIBRARY) && !this.reactive) { + } else if (this.openapiDocketConfig && !library.equals(SPRING_CLOUD_LIBRARY) && !this.reactive) { supportingFiles.add(new SupportingFile("openapiDocumentationConfig.mustache", (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "OpenAPIDocumentationConfig.java")); } @@ -378,18 +375,10 @@ public void processOpts() { } // add lambda for mustache templates - additionalProperties.put("lambdaEscapeDoubleQuote", new Mustache.Lambda() { - @Override - public void execute(Template.Fragment fragment, Writer writer) throws IOException { - writer.write(fragment.execute().replaceAll("\"", Matcher.quoteReplacement("\\\""))); - } - }); - additionalProperties.put("lambdaRemoveLineBreak", new Mustache.Lambda() { - @Override - public void execute(Template.Fragment fragment, Writer writer) throws IOException { - writer.write(fragment.execute().replaceAll("\\r|\\n", "")); - } - }); + additionalProperties.put("lambdaEscapeDoubleQuote", + (Mustache.Lambda) (fragment, writer) -> writer.write(fragment.execute().replaceAll("\"", Matcher.quoteReplacement("\\\"")))); + additionalProperties.put("lambdaRemoveLineBreak", + (Mustache.Lambda) (fragment, writer) -> writer.write(fragment.execute().replaceAll("\\r|\\n", ""))); } @Override @@ -409,11 +398,7 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera } else { co.subresourceOperation = !co.path.isEmpty(); } - List opList = operations.get(basePath); - if (opList == null) { - opList = new ArrayList(); - operations.put(basePath, opList); - } + List opList = operations.computeIfAbsent(basePath, k -> new ArrayList<>()); opList.add(co); co.baseName = basePath; } else { @@ -674,8 +659,8 @@ public void setImplicitHeaders(boolean implicitHeaders) { this.implicitHeaders = implicitHeaders; } - public void setSwaggerDocketConfig(boolean swaggerDocketConfig) { - this.swaggerDocketConfig = swaggerDocketConfig; + public void setOpenapiDocketConfig(boolean openapiDocketConfig) { + this.openapiDocketConfig = openapiDocketConfig; } @Override diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/apiController.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/apiController.mustache index e803e6502c66..27e60454acf3 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/apiController.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/apiController.mustache @@ -13,6 +13,9 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +{{/jdk8}} +import org.springframework.web.bind.annotation.RequestMapping; +{{^jdk8}} import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; {{/jdk8}} @@ -44,6 +47,9 @@ import java.util.concurrent.Callable; {{/jdk8}} {{>generatedAnnotation}} @Controller +{{=<% %>=}} +@RequestMapping("${openapi.<%title%>.base-path:<%>defaultBasePath%>}") +<%={{ }}=%> {{#operations}} public class {{classname}}Controller implements {{classname}} { diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/application.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/application.mustache index 4db5be911cbb..726647a19eb3 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/application.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/application.mustache @@ -1,5 +1,4 @@ springfox.documentation.swagger.v2.path=/api-docs -server.{{#java8}}servlet.{{/java8}}context-path={{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}} server.port={{serverPort}} spring.jackson.date-format={{basePackage}}.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/README.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/README.mustache index f4827164a1ef..2f401bb621b0 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/README.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/README.mustache @@ -12,7 +12,7 @@ The underlying library integrating OpenAPI to SpringBoot is [springfox](https:// Start your server as an simple java application -{{#reactive}} +{{^reactive}} You can view the api documentation in swagger-ui by pointing to http://localhost:8080/ diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/defaultBasePath.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/defaultBasePath.mustache new file mode 100644 index 000000000000..3c7185bd6289 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/defaultBasePath.mustache @@ -0,0 +1 @@ +{{contextPath}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-mvc/defaultBasePath.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-mvc/defaultBasePath.mustache new file mode 100644 index 000000000000..35ec3b9d7586 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-mvc/defaultBasePath.mustache @@ -0,0 +1 @@ +/ \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-mvc/openapiUiConfiguration.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-mvc/openapiUiConfiguration.mustache index 09fa3ed0c123..2092ed66ffcd 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-mvc/openapiUiConfiguration.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-mvc/openapiUiConfiguration.mustache @@ -28,7 +28,7 @@ import java.util.List; @Configuration @ComponentScan(basePackages = "{{apiPackage}}") @EnableWebMvc -@PropertySource("classpath:swagger.properties") +@PropertySource("classpath:openapi.properties") @Import(OpenAPIDocumentationConfig.class) public class OpenAPIUiConfiguration extends WebMvcConfigurerAdapter { private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" }; diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/openapiDocumentationConfig.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/openapiDocumentationConfig.mustache index e576906d5b80..7dd911a1ae56 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/openapiDocumentationConfig.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/openapiDocumentationConfig.mustache @@ -1,19 +1,24 @@ package {{configPackage}}; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; -{{#useOptional}} +{{#useOptional}} import java.util.Optional; {{/useOptional}} +import javax.servlet.ServletContext; {{>generatedAnnotation}} @Configuration @@ -33,12 +38,15 @@ public class OpenAPIDocumentationConfig { } @Bean - public Docket customImplementation(){ +{{=<% %>=}} + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.<%title%>.base-path:<%>defaultBasePath%>}") String basePath) { +<%={{ }}=%> return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("{{apiPackage}}")) .build() {{#java8}} + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) {{/java8}} @@ -56,4 +64,25 @@ public class OpenAPIDocumentationConfig { .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/AnotherFakeApiController.java index a00284b15e76..d0e45c0458b9 100644 --- a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class AnotherFakeApiController implements AnotherFakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeApiController.java index b9cfa40cde32..16d3908be7cd 100644 --- a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class FakeApiController implements FakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index f3b7fa0a14ab..709a1981f75f 100644 --- a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/PetApiController.java index 2afbaa68af58..e6d6429de31e 100644 --- a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/PetApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class PetApiController implements PetApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/StoreApiController.java index a56c2f1d774d..c4cd0487fb88 100644 --- a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/StoreApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class StoreApiController implements StoreApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/UserApiController.java index 0577fc8f3458..07044abe99c9 100644 --- a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/UserApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class UserApiController implements UserApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java index e5dbf694c6a0..3ad72e748287 100644 --- a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java +++ b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java @@ -1,16 +1,22 @@ package org.openapitools.configuration; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; +import javax.servlet.ServletContext; + @Configuration @EnableSwagger2 @@ -29,14 +35,36 @@ ApiInfo apiInfo() { } @Bean - public Docket customImplementation(){ + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.openAPIPetstore.base-path:/}") String basePath) { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java index e8aacb697c8f..2840efe3f193 100644 --- a/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java +++ b/samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java @@ -20,7 +20,7 @@ @Configuration @ComponentScan(basePackages = "org.openapitools.api") @EnableWebMvc -@PropertySource("classpath:swagger.properties") +@PropertySource("classpath:openapi.properties") @Import(OpenAPIDocumentationConfig.class) public class OpenAPIUiConfiguration extends WebMvcConfigurerAdapter { private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" }; diff --git a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/AnotherFakeApiController.java index a00284b15e76..d0e45c0458b9 100644 --- a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class AnotherFakeApiController implements AnotherFakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/FakeApiController.java index b9cfa40cde32..16d3908be7cd 100644 --- a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/FakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class FakeApiController implements FakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index f3b7fa0a14ab..709a1981f75f 100644 --- a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/PetApiController.java index 2afbaa68af58..e6d6429de31e 100644 --- a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/PetApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class PetApiController implements PetApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/StoreApiController.java index a56c2f1d774d..c4cd0487fb88 100644 --- a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/StoreApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class StoreApiController implements StoreApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/UserApiController.java index 0577fc8f3458..07044abe99c9 100644 --- a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/api/UserApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class UserApiController implements UserApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java index e5dbf694c6a0..3ad72e748287 100644 --- a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java +++ b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java @@ -1,16 +1,22 @@ package org.openapitools.configuration; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; +import javax.servlet.ServletContext; + @Configuration @EnableSwagger2 @@ -29,14 +35,36 @@ ApiInfo apiInfo() { } @Bean - public Docket customImplementation(){ + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.openAPIPetstore.base-path:/}") String basePath) { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java index e8aacb697c8f..2840efe3f193 100644 --- a/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java +++ b/samples/server/petstore/spring-mvc-j8-localdatetime/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java @@ -20,7 +20,7 @@ @Configuration @ComponentScan(basePackages = "org.openapitools.api") @EnableWebMvc -@PropertySource("classpath:swagger.properties") +@PropertySource("classpath:openapi.properties") @Import(OpenAPIDocumentationConfig.class) public class OpenAPIUiConfiguration extends WebMvcConfigurerAdapter { private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" }; diff --git a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/AnotherFakeApiController.java index 7f65672fd6d6..b2bef5774095 100644 --- a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -20,6 +21,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class AnotherFakeApiController implements AnotherFakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/FakeApiController.java index fbc64cebd7b5..624be6d6926a 100644 --- a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/FakeApiController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -27,6 +28,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class FakeApiController implements FakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index 0e62baafdcd5..1b4e5db5f8b9 100644 --- a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -20,6 +21,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/PetApiController.java index 30fc3b600f07..20ea8d651a4f 100644 --- a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/PetApiController.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -22,6 +23,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class PetApiController implements PetApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/StoreApiController.java index df35dbc4a7f5..ba21fb432e80 100644 --- a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/StoreApiController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -21,6 +22,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class StoreApiController implements StoreApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/UserApiController.java index c8107c570f64..eb642e22c137 100644 --- a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/api/UserApiController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -21,6 +22,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/}") public class UserApiController implements UserApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java index b36e2ad7d3ea..68e2e36f3704 100644 --- a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java +++ b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java @@ -1,16 +1,22 @@ package org.openapitools.configuration; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; +import javax.servlet.ServletContext; + @Configuration @EnableSwagger2 @@ -29,11 +35,12 @@ ApiInfo apiInfo() { } @Bean - public Docket customImplementation(){ + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.openAPIPetstore.base-path:/}") String basePath) { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) .directModelSubstitute(org.threeten.bp.LocalDate.class, java.sql.Date.class) @@ -41,4 +48,25 @@ public Docket customImplementation(){ .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java index c17d539e2fce..d67b926b3470 100644 --- a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java +++ b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/OpenAPIUiConfiguration.java @@ -24,7 +24,7 @@ @Configuration @ComponentScan(basePackages = "org.openapitools.api") @EnableWebMvc -@PropertySource("classpath:swagger.properties") +@PropertySource("classpath:openapi.properties") @Import(OpenAPIDocumentationConfig.class) public class OpenAPIUiConfiguration extends WebMvcConfigurerAdapter { private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" }; diff --git a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/SwaggerUiConfiguration.java b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/SwaggerUiConfiguration.java index 041df1dc4418..380983cce8e9 100644 --- a/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/SwaggerUiConfiguration.java +++ b/samples/server/petstore/spring-mvc/src/main/java/org/openapitools/configuration/SwaggerUiConfiguration.java @@ -24,7 +24,7 @@ @Configuration @ComponentScan(basePackages = "org.openapitools.api") @EnableWebMvc -@PropertySource("classpath:swagger.properties") +@PropertySource("classpath:openapi.properties") @Import(SwaggerDocumentationConfig.class) public class SwaggerUiConfiguration extends WebMvcConfigurerAdapter { private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" }; diff --git a/samples/server/petstore/springboot-beanvalidation/README.md b/samples/server/petstore/springboot-beanvalidation/README.md index a12a59c79ed0..f7a85c933038 100644 --- a/samples/server/petstore/springboot-beanvalidation/README.md +++ b/samples/server/petstore/springboot-beanvalidation/README.md @@ -12,4 +12,7 @@ The underlying library integrating OpenAPI to SpringBoot is [springfox](https:// Start your server as an simple java application +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/ + Change default port value in application.properties \ No newline at end of file diff --git a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/AnotherFakeApiController.java index 7f65672fd6d6..4be8a57963d4 100644 --- a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -20,6 +21,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class AnotherFakeApiController implements AnotherFakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/FakeApiController.java index fbc64cebd7b5..26af39e6eb1b 100644 --- a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/FakeApiController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -27,6 +28,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeApiController implements FakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index 0e62baafdcd5..d10cfe7c51df 100644 --- a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -20,6 +21,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/PetApiController.java index 30fc3b600f07..b01cdf874b30 100644 --- a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/PetApiController.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -22,6 +23,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class PetApiController implements PetApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/StoreApiController.java index df35dbc4a7f5..34e3cb7d8fcc 100644 --- a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/StoreApiController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -21,6 +22,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class StoreApiController implements StoreApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/UserApiController.java index c8107c570f64..69da699f5eea 100644 --- a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/api/UserApiController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.NativeWebRequest; @@ -21,6 +22,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class UserApiController implements UserApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java index b36e2ad7d3ea..3307fc00b59d 100644 --- a/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java +++ b/samples/server/petstore/springboot-beanvalidation/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java @@ -1,16 +1,22 @@ package org.openapitools.configuration; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; +import javax.servlet.ServletContext; + @Configuration @EnableSwagger2 @@ -29,11 +35,12 @@ ApiInfo apiInfo() { } @Bean - public Docket customImplementation(){ + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.openAPIPetstore.base-path:/v2}") String basePath) { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) .directModelSubstitute(org.threeten.bp.LocalDate.class, java.sql.Date.class) @@ -41,4 +48,25 @@ public Docket customImplementation(){ .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/springboot-beanvalidation/src/main/resources/application.properties b/samples/server/petstore/springboot-beanvalidation/src/main/resources/application.properties index f2f5ff7328bd..13b0dc6ab966 100644 --- a/samples/server/petstore/springboot-beanvalidation/src/main/resources/application.properties +++ b/samples/server/petstore/springboot-beanvalidation/src/main/resources/application.properties @@ -1,5 +1,4 @@ springfox.documentation.swagger.v2.path=/api-docs -server.servlet.context-path=/v2 server.port=80 spring.jackson.date-format=org.openapitools.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false \ No newline at end of file diff --git a/samples/server/petstore/springboot-delegate-j8/README.md b/samples/server/petstore/springboot-delegate-j8/README.md index a12a59c79ed0..f7a85c933038 100644 --- a/samples/server/petstore/springboot-delegate-j8/README.md +++ b/samples/server/petstore/springboot-delegate-j8/README.md @@ -12,4 +12,7 @@ The underlying library integrating OpenAPI to SpringBoot is [springfox](https:// Start your server as an simple java application +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/ + Change default port value in application.properties \ No newline at end of file diff --git a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/AnotherFakeApiController.java index aa3ed63ed30a..61e97d7814f0 100644 --- a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -1,8 +1,10 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class AnotherFakeApiController implements AnotherFakeApi { private final AnotherFakeApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeApiController.java index 19c5c7fbdb1c..34a7673e718f 100644 --- a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeApiController.java @@ -1,8 +1,10 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeApiController implements FakeApi { private final FakeApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index b425216f425c..a749febeb421 100644 --- a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -1,8 +1,10 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { private final FakeClassnameTestApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/PetApiController.java index 2f78bfd40e05..fafdaa617ee1 100644 --- a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/PetApiController.java @@ -1,8 +1,10 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class PetApiController implements PetApi { private final PetApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/StoreApiController.java index f726a244a365..4a1050efbe7d 100644 --- a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/StoreApiController.java @@ -1,8 +1,10 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class StoreApiController implements StoreApi { private final StoreApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/UserApiController.java index 51c8f35fcbf9..3e61422e7045 100644 --- a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/UserApiController.java @@ -1,8 +1,10 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class UserApiController implements UserApi { private final UserApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java index e5dbf694c6a0..77dca61d0e57 100644 --- a/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java +++ b/samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java @@ -1,16 +1,22 @@ package org.openapitools.configuration; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; +import javax.servlet.ServletContext; + @Configuration @EnableSwagger2 @@ -29,14 +35,36 @@ ApiInfo apiInfo() { } @Bean - public Docket customImplementation(){ + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.openAPIPetstore.base-path:/v2}") String basePath) { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/springboot-delegate-j8/src/main/resources/application.properties b/samples/server/petstore/springboot-delegate-j8/src/main/resources/application.properties index f2f5ff7328bd..13b0dc6ab966 100644 --- a/samples/server/petstore/springboot-delegate-j8/src/main/resources/application.properties +++ b/samples/server/petstore/springboot-delegate-j8/src/main/resources/application.properties @@ -1,5 +1,4 @@ springfox.documentation.swagger.v2.path=/api-docs -server.servlet.context-path=/v2 server.port=80 spring.jackson.date-format=org.openapitools.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false \ No newline at end of file diff --git a/samples/server/petstore/springboot-delegate/README.md b/samples/server/petstore/springboot-delegate/README.md index a12a59c79ed0..f7a85c933038 100644 --- a/samples/server/petstore/springboot-delegate/README.md +++ b/samples/server/petstore/springboot-delegate/README.md @@ -12,4 +12,7 @@ The underlying library integrating OpenAPI to SpringBoot is [springfox](https:// Start your server as an simple java application +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/ + Change default port value in application.properties \ No newline at end of file diff --git a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/AnotherFakeApiController.java index 5d462572a2c5..5e529601b887 100644 --- a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; @@ -19,6 +20,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class AnotherFakeApiController implements AnotherFakeApi { private final AnotherFakeApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApiController.java index 918c3ca6306a..5d5d7c39f0c2 100644 --- a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApiController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; @@ -26,6 +27,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeApiController implements FakeApi { private final FakeApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index 28ac51f555f8..2ba0c8f243c7 100644 --- a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; @@ -19,6 +20,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { private final FakeClassnameTestApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/PetApiController.java index d8126798dd93..9f2b29ca1bc7 100644 --- a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/PetApiController.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; @@ -21,6 +22,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class PetApiController implements PetApi { private final PetApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/StoreApiController.java index 7614d6046c1f..a3be091a8a5c 100644 --- a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/StoreApiController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; @@ -20,6 +21,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class StoreApiController implements StoreApi { private final StoreApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/UserApiController.java index bf404b20ee75..62084ee17e72 100644 --- a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/UserApiController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; @@ -20,6 +21,7 @@ import java.util.Map; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class UserApiController implements UserApi { private final UserApiDelegate delegate; diff --git a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java index b36e2ad7d3ea..3307fc00b59d 100644 --- a/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java +++ b/samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java @@ -1,16 +1,22 @@ package org.openapitools.configuration; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; +import javax.servlet.ServletContext; + @Configuration @EnableSwagger2 @@ -29,11 +35,12 @@ ApiInfo apiInfo() { } @Bean - public Docket customImplementation(){ + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.openAPIPetstore.base-path:/v2}") String basePath) { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) .directModelSubstitute(org.threeten.bp.LocalDate.class, java.sql.Date.class) @@ -41,4 +48,25 @@ public Docket customImplementation(){ .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/springboot-delegate/src/main/resources/application.properties b/samples/server/petstore/springboot-delegate/src/main/resources/application.properties index f2f5ff7328bd..13b0dc6ab966 100644 --- a/samples/server/petstore/springboot-delegate/src/main/resources/application.properties +++ b/samples/server/petstore/springboot-delegate/src/main/resources/application.properties @@ -1,5 +1,4 @@ springfox.documentation.swagger.v2.path=/api-docs -server.servlet.context-path=/v2 server.port=80 spring.jackson.date-format=org.openapitools.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false \ No newline at end of file diff --git a/samples/server/petstore/springboot-implicitHeaders/README.md b/samples/server/petstore/springboot-implicitHeaders/README.md index a12a59c79ed0..f7a85c933038 100644 --- a/samples/server/petstore/springboot-implicitHeaders/README.md +++ b/samples/server/petstore/springboot-implicitHeaders/README.md @@ -12,4 +12,7 @@ The underlying library integrating OpenAPI to SpringBoot is [springfox](https:// Start your server as an simple java application +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/ + Change default port value in application.properties \ No newline at end of file diff --git a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/AnotherFakeApiController.java index a00284b15e76..fff17a03c074 100644 --- a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class AnotherFakeApiController implements AnotherFakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/FakeApiController.java index b9cfa40cde32..36a7304885eb 100644 --- a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/FakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeApiController implements FakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index f3b7fa0a14ab..f4cccda6d621 100644 --- a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/PetApiController.java index 2afbaa68af58..1138014eedf7 100644 --- a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/PetApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class PetApiController implements PetApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/StoreApiController.java index a56c2f1d774d..7b2593af1b1c 100644 --- a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/StoreApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class StoreApiController implements StoreApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/UserApiController.java index 0577fc8f3458..5eca262e4327 100644 --- a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/UserApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class UserApiController implements UserApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java index e5dbf694c6a0..77dca61d0e57 100644 --- a/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java +++ b/samples/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java @@ -1,16 +1,22 @@ package org.openapitools.configuration; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; +import javax.servlet.ServletContext; + @Configuration @EnableSwagger2 @@ -29,14 +35,36 @@ ApiInfo apiInfo() { } @Bean - public Docket customImplementation(){ + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.openAPIPetstore.base-path:/v2}") String basePath) { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/springboot-implicitHeaders/src/main/resources/application.properties b/samples/server/petstore/springboot-implicitHeaders/src/main/resources/application.properties index f2f5ff7328bd..13b0dc6ab966 100644 --- a/samples/server/petstore/springboot-implicitHeaders/src/main/resources/application.properties +++ b/samples/server/petstore/springboot-implicitHeaders/src/main/resources/application.properties @@ -1,5 +1,4 @@ springfox.documentation.swagger.v2.path=/api-docs -server.servlet.context-path=/v2 server.port=80 spring.jackson.date-format=org.openapitools.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false \ No newline at end of file diff --git a/samples/server/petstore/springboot-reactive/README.md b/samples/server/petstore/springboot-reactive/README.md index f7a85c933038..a12a59c79ed0 100644 --- a/samples/server/petstore/springboot-reactive/README.md +++ b/samples/server/petstore/springboot-reactive/README.md @@ -12,7 +12,4 @@ The underlying library integrating OpenAPI to SpringBoot is [springfox](https:// Start your server as an simple java application -You can view the api documentation in swagger-ui by pointing to -http://localhost:8080/ - Change default port value in application.properties \ No newline at end of file diff --git a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/AnotherFakeApiController.java index 54400415902d..95aa3755fdc4 100644 --- a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class AnotherFakeApiController implements AnotherFakeApi { diff --git a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/FakeApiController.java index 883e35abadea..19e8a7d37b6f 100644 --- a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/FakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeApiController implements FakeApi { diff --git a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index d404f5a7c1af..34e056fe92b0 100644 --- a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { diff --git a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/PetApiController.java index 6b2d96d5caf9..e98cd3de1f2f 100644 --- a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/PetApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class PetApiController implements PetApi { diff --git a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/StoreApiController.java index 46390ca6ae2a..63e475b64216 100644 --- a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/StoreApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class StoreApiController implements StoreApi { diff --git a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/UserApiController.java index 56bf41484f53..92f2624d96bc 100644 --- a/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/springboot-reactive/src/main/java/org/openapitools/api/UserApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class UserApiController implements UserApi { diff --git a/samples/server/petstore/springboot-reactive/src/main/resources/application.properties b/samples/server/petstore/springboot-reactive/src/main/resources/application.properties index f2f5ff7328bd..13b0dc6ab966 100644 --- a/samples/server/petstore/springboot-reactive/src/main/resources/application.properties +++ b/samples/server/petstore/springboot-reactive/src/main/resources/application.properties @@ -1,5 +1,4 @@ springfox.documentation.swagger.v2.path=/api-docs -server.servlet.context-path=/v2 server.port=80 spring.jackson.date-format=org.openapitools.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false \ No newline at end of file diff --git a/samples/server/petstore/springboot-useoptional/README.md b/samples/server/petstore/springboot-useoptional/README.md index a12a59c79ed0..f7a85c933038 100644 --- a/samples/server/petstore/springboot-useoptional/README.md +++ b/samples/server/petstore/springboot-useoptional/README.md @@ -12,4 +12,7 @@ The underlying library integrating OpenAPI to SpringBoot is [springfox](https:// Start your server as an simple java application +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/ + Change default port value in application.properties \ No newline at end of file diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/AnotherFakeApiController.java index a00284b15e76..fff17a03c074 100644 --- a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class AnotherFakeApiController implements AnotherFakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/FakeApiController.java index b9cfa40cde32..36a7304885eb 100644 --- a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/FakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeApiController implements FakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index f3b7fa0a14ab..f4cccda6d621 100644 --- a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/PetApiController.java index 2afbaa68af58..1138014eedf7 100644 --- a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/PetApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class PetApiController implements PetApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/StoreApiController.java index a56c2f1d774d..7b2593af1b1c 100644 --- a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/StoreApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class StoreApiController implements StoreApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/UserApiController.java index 0577fc8f3458..5eca262e4327 100644 --- a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/UserApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class UserApiController implements UserApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java index 13e16885a871..0a9d8095dd59 100644 --- a/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java +++ b/samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java @@ -1,17 +1,22 @@ package org.openapitools.configuration; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.Optional; +import javax.servlet.ServletContext; @Configuration @@ -31,15 +36,37 @@ ApiInfo apiInfo() { } @Bean - public Docket customImplementation(){ + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.openAPIPetstore.base-path:/v2}") String basePath) { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) .genericModelSubstitutes(Optional.class) .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/springboot-useoptional/src/main/resources/application.properties b/samples/server/petstore/springboot-useoptional/src/main/resources/application.properties index f2f5ff7328bd..13b0dc6ab966 100644 --- a/samples/server/petstore/springboot-useoptional/src/main/resources/application.properties +++ b/samples/server/petstore/springboot-useoptional/src/main/resources/application.properties @@ -1,5 +1,4 @@ springfox.documentation.swagger.v2.path=/api-docs -server.servlet.context-path=/v2 server.port=80 spring.jackson.date-format=org.openapitools.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false \ No newline at end of file diff --git a/samples/server/petstore/springboot/README.md b/samples/server/petstore/springboot/README.md index a12a59c79ed0..f7a85c933038 100644 --- a/samples/server/petstore/springboot/README.md +++ b/samples/server/petstore/springboot/README.md @@ -12,4 +12,7 @@ The underlying library integrating OpenAPI to SpringBoot is [springfox](https:// Start your server as an simple java application +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/ + Change default port value in application.properties \ No newline at end of file diff --git a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/AnotherFakeApiController.java b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/AnotherFakeApiController.java index a00284b15e76..fff17a03c074 100644 --- a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/AnotherFakeApiController.java +++ b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/AnotherFakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class AnotherFakeApiController implements AnotherFakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/FakeApiController.java b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/FakeApiController.java index b9cfa40cde32..36a7304885eb 100644 --- a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/FakeApiController.java +++ b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/FakeApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeApiController implements FakeApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java index f3b7fa0a14ab..f4cccda6d621 100644 --- a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java +++ b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/FakeClassnameTestApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class FakeClassnameTestApiController implements FakeClassnameTestApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/PetApiController.java b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/PetApiController.java index 2afbaa68af58..1138014eedf7 100644 --- a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/PetApiController.java +++ b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/PetApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class PetApiController implements PetApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/StoreApiController.java b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/StoreApiController.java index a56c2f1d774d..7b2593af1b1c 100644 --- a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/StoreApiController.java +++ b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/StoreApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class StoreApiController implements StoreApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/UserApiController.java index 0577fc8f3458..5eca262e4327 100644 --- a/samples/server/petstore/springboot/src/main/java/org/openapitools/api/UserApiController.java +++ b/samples/server/petstore/springboot/src/main/java/org/openapitools/api/UserApiController.java @@ -1,10 +1,12 @@ package org.openapitools.api; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.NativeWebRequest; import java.util.Optional; @Controller +@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}") public class UserApiController implements UserApi { private final NativeWebRequest request; diff --git a/samples/server/petstore/springboot/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/springboot/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java index e5dbf694c6a0..77dca61d0e57 100644 --- a/samples/server/petstore/springboot/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java +++ b/samples/server/petstore/springboot/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java @@ -1,16 +1,22 @@ package org.openapitools.configuration; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.UriComponentsBuilder; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.Paths; +import springfox.documentation.spring.web.paths.RelativePathProvider; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; +import javax.servlet.ServletContext; + @Configuration @EnableSwagger2 @@ -29,14 +35,36 @@ ApiInfo apiInfo() { } @Bean - public Docket customImplementation(){ + public Docket customImplementation(ServletContext servletContext, @Value("${openapi.openAPIPetstore.base-path:/v2}") String basePath) { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.openapitools.api")) .build() + .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath)) .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) .apiInfo(apiInfo()); } + class BasePathAwareRelativePathProvider extends RelativePathProvider { + private String basePath; + + public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) { + super(servletContext); + this.basePath = basePath; + } + + @Override + protected String applicationPath() { + return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString()); + } + + @Override + public String getOperationPath(String operationPath) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/"); + return Paths.removeAdjacentForwardSlashes( + uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString()); + } + } + } diff --git a/samples/server/petstore/springboot/src/main/resources/application.properties b/samples/server/petstore/springboot/src/main/resources/application.properties index f2f5ff7328bd..13b0dc6ab966 100644 --- a/samples/server/petstore/springboot/src/main/resources/application.properties +++ b/samples/server/petstore/springboot/src/main/resources/application.properties @@ -1,5 +1,4 @@ springfox.documentation.swagger.v2.path=/api-docs -server.servlet.context-path=/v2 server.port=80 spring.jackson.date-format=org.openapitools.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false \ No newline at end of file