Skip to content

Commit 71b5de3

Browse files
cbornetwing328
authored andcommitted
Do not set contextPath for spring-boot (OpenAPITools#104)
1 parent 1a4e5a4 commit 71b5de3

File tree

95 files changed

+457
-57
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+457
-57
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.openapitools.codegen.languages;
1919

2020
import com.samskivert.mustache.Mustache;
21-
import com.samskivert.mustache.Template;
2221

2322
import io.swagger.v3.oas.models.OpenAPI;
2423
import io.swagger.v3.oas.models.Operation;
@@ -41,8 +40,6 @@
4140
import org.slf4j.LoggerFactory;
4241

4342
import java.io.File;
44-
import java.io.IOException;
45-
import java.io.Writer;
4643
import java.net.URL;
4744
import java.util.ArrayList;
4845
import java.util.Arrays;
@@ -71,7 +68,7 @@ public class SpringCodegen extends AbstractJavaCodegen
7168
public static final String SPRING_BOOT = "spring-boot";
7269
public static final String SPRING_CLOUD_LIBRARY = "spring-cloud";
7370
public static final String IMPLICIT_HEADERS = "implicitHeaders";
74-
public static final String SWAGGER_DOCKET_CONFIG = "swaggerDocketConfig";
71+
public static final String OPENAPI_DOCKET_CONFIG = "swaggerDocketConfig";
7572

7673
protected String title = "OpenAPI Spring";
7774
protected String configPackage = "org.openapitools.configuration";
@@ -87,7 +84,7 @@ public class SpringCodegen extends AbstractJavaCodegen
8784
protected boolean useTags = false;
8885
protected boolean useBeanValidation = true;
8986
protected boolean implicitHeaders = false;
90-
protected boolean swaggerDocketConfig = false;
87+
protected boolean openapiDocketConfig = false;
9188
protected boolean useOptional = false;
9289

9390
public SpringCodegen() {
@@ -116,7 +113,7 @@ public SpringCodegen() {
116113
cliOptions.add(CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames"));
117114
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
118115
cliOptions.add(CliOption.newBoolean(IMPLICIT_HEADERS, "Use of @ApiImplicitParams for headers."));
119-
cliOptions.add(CliOption.newBoolean(SWAGGER_DOCKET_CONFIG, "Generate Spring Swagger Docket configuration class."));
116+
cliOptions.add(CliOption.newBoolean(OPENAPI_DOCKET_CONFIG, "Generate Spring OpenAPI Docket configuration class."));
120117
cliOptions.add(CliOption.newBoolean(USE_OPTIONAL,
121118
"Use Optional container for optional parameters"));
122119

@@ -235,8 +232,8 @@ public void processOpts() {
235232
this.setImplicitHeaders(Boolean.valueOf(additionalProperties.get(IMPLICIT_HEADERS).toString()));
236233
}
237234

238-
if (additionalProperties.containsKey(SWAGGER_DOCKET_CONFIG)) {
239-
this.setSwaggerDocketConfig(Boolean.valueOf(additionalProperties.get(SWAGGER_DOCKET_CONFIG).toString()));
235+
if (additionalProperties.containsKey(OPENAPI_DOCKET_CONFIG)) {
236+
this.setOpenapiDocketConfig(Boolean.valueOf(additionalProperties.get(OPENAPI_DOCKET_CONFIG).toString()));
240237
}
241238

242239
typeMapping.put("file", "Resource");
@@ -283,7 +280,7 @@ public void processOpts() {
283280
supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache",
284281
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "RFC3339DateFormat.java"));
285282
supportingFiles.add(new SupportingFile("application.properties",
286-
("src.main.resources").replace(".", java.io.File.separator), "swagger.properties"));
283+
("src.main.resources").replace(".", java.io.File.separator), "openapi.properties"));
287284
}
288285
if (library.equals(SPRING_CLOUD_LIBRARY)) {
289286
supportingFiles.add(new SupportingFile("apiKeyRequestInterceptor.mustache",
@@ -310,7 +307,7 @@ public void processOpts() {
310307
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "OpenAPIDocumentationConfig.java"));
311308
}
312309
}
313-
} else if (this.swaggerDocketConfig && !library.equals(SPRING_CLOUD_LIBRARY) && !this.reactive) {
310+
} else if (this.openapiDocketConfig && !library.equals(SPRING_CLOUD_LIBRARY) && !this.reactive) {
314311
supportingFiles.add(new SupportingFile("openapiDocumentationConfig.mustache",
315312
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "OpenAPIDocumentationConfig.java"));
316313
}
@@ -378,18 +375,10 @@ public void processOpts() {
378375
}
379376

380377
// add lambda for mustache templates
381-
additionalProperties.put("lambdaEscapeDoubleQuote", new Mustache.Lambda() {
382-
@Override
383-
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
384-
writer.write(fragment.execute().replaceAll("\"", Matcher.quoteReplacement("\\\"")));
385-
}
386-
});
387-
additionalProperties.put("lambdaRemoveLineBreak", new Mustache.Lambda() {
388-
@Override
389-
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
390-
writer.write(fragment.execute().replaceAll("\\r|\\n", ""));
391-
}
392-
});
378+
additionalProperties.put("lambdaEscapeDoubleQuote",
379+
(Mustache.Lambda) (fragment, writer) -> writer.write(fragment.execute().replaceAll("\"", Matcher.quoteReplacement("\\\""))));
380+
additionalProperties.put("lambdaRemoveLineBreak",
381+
(Mustache.Lambda) (fragment, writer) -> writer.write(fragment.execute().replaceAll("\\r|\\n", "")));
393382
}
394383

395384
@Override
@@ -409,11 +398,7 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera
409398
} else {
410399
co.subresourceOperation = !co.path.isEmpty();
411400
}
412-
List<CodegenOperation> opList = operations.get(basePath);
413-
if (opList == null) {
414-
opList = new ArrayList<CodegenOperation>();
415-
operations.put(basePath, opList);
416-
}
401+
List<CodegenOperation> opList = operations.computeIfAbsent(basePath, k -> new ArrayList<>());
417402
opList.add(co);
418403
co.baseName = basePath;
419404
} else {
@@ -674,8 +659,8 @@ public void setImplicitHeaders(boolean implicitHeaders) {
674659
this.implicitHeaders = implicitHeaders;
675660
}
676661

677-
public void setSwaggerDocketConfig(boolean swaggerDocketConfig) {
678-
this.swaggerDocketConfig = swaggerDocketConfig;
662+
public void setOpenapiDocketConfig(boolean openapiDocketConfig) {
663+
this.openapiDocketConfig = openapiDocketConfig;
679664
}
680665

681666
@Override

modules/openapi-generator/src/main/resources/JavaSpring/apiController.mustache

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import org.springframework.stereotype.Controller;
1313
import org.springframework.web.bind.annotation.PathVariable;
1414
import org.springframework.web.bind.annotation.RequestBody;
1515
import org.springframework.web.bind.annotation.RequestHeader;
16+
{{/jdk8}}
17+
import org.springframework.web.bind.annotation.RequestMapping;
18+
{{^jdk8}}
1619
import org.springframework.web.bind.annotation.RequestParam;
1720
import org.springframework.web.bind.annotation.RequestPart;
1821
{{/jdk8}}
@@ -39,6 +42,9 @@ import java.util.concurrent.Callable;
3942
{{/jdk8}}
4043
{{>generatedAnnotation}}
4144
@Controller
45+
{{=<% %>=}}
46+
@RequestMapping("${openapi.<%title%>.base-path:<%>defaultBasePath%>}")
47+
<%={{ }}=%>
4248
{{#operations}}
4349
public class {{classname}}Controller implements {{classname}} {
4450
{{#isDelegate}}
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
springfox.documentation.swagger.v2.path=/api-docs
2-
server.{{#java8}}servlet.{{/java8}}context-path={{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}}
32
server.port={{serverPort}}
43
spring.jackson.date-format={{basePackage}}.RFC3339DateFormat
54
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false

modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/README.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The underlying library integrating OpenAPI to SpringBoot is [springfox](https://
1212

1313
Start your server as an simple java application
1414

15-
{{#reactive}}
15+
{{^reactive}}
1616
You can view the api documentation in swagger-ui by pointing to
1717
http://localhost:8080/
1818

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{contextPath}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/

modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-mvc/openapiUiConfiguration.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import java.util.List;
2828
@Configuration
2929
@ComponentScan(basePackages = "{{apiPackage}}")
3030
@EnableWebMvc
31-
@PropertySource("classpath:swagger.properties")
31+
@PropertySource("classpath:openapi.properties")
3232
@Import(OpenAPIDocumentationConfig.class)
3333
public class OpenAPIUiConfiguration extends WebMvcConfigurerAdapter {
3434
private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" };

modules/openapi-generator/src/main/resources/JavaSpring/openapiDocumentationConfig.mustache

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
package {{configPackage}};
22

3+
import org.springframework.beans.factory.annotation.Value;
34
import org.springframework.context.annotation.Bean;
45
import org.springframework.context.annotation.Configuration;
56

7+
import org.springframework.web.util.UriComponentsBuilder;
68
import springfox.documentation.builders.ApiInfoBuilder;
79
import springfox.documentation.builders.RequestHandlerSelectors;
810
import springfox.documentation.service.ApiInfo;
911
import springfox.documentation.service.Contact;
1012
import springfox.documentation.spi.DocumentationType;
13+
import springfox.documentation.spring.web.paths.Paths;
14+
import springfox.documentation.spring.web.paths.RelativePathProvider;
1115
import springfox.documentation.spring.web.plugins.Docket;
1216
import springfox.documentation.swagger2.annotations.EnableSwagger2;
13-
{{#useOptional}}
1417

18+
{{#useOptional}}
1519
import java.util.Optional;
1620
{{/useOptional}}
21+
import javax.servlet.ServletContext;
1722

1823
{{>generatedAnnotation}}
1924
@Configuration
@@ -33,12 +38,15 @@ public class OpenAPIDocumentationConfig {
3338
}
3439

3540
@Bean
36-
public Docket customImplementation(){
41+
{{=<% %>=}}
42+
public Docket customImplementation(ServletContext servletContext, @Value("${openapi.<%title%>.base-path:<%>defaultBasePath%>}") String basePath) {
43+
<%={{ }}=%>
3744
return new Docket(DocumentationType.SWAGGER_2)
3845
.select()
3946
.apis(RequestHandlerSelectors.basePackage("{{apiPackage}}"))
4047
.build()
4148
{{#java8}}
49+
.pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath))
4250
.directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class)
4351
.directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class)
4452
{{/java8}}
@@ -56,4 +64,25 @@ public class OpenAPIDocumentationConfig {
5664
.apiInfo(apiInfo());
5765
}
5866

67+
class BasePathAwareRelativePathProvider extends RelativePathProvider {
68+
private String basePath;
69+
70+
public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) {
71+
super(servletContext);
72+
this.basePath = basePath;
73+
}
74+
75+
@Override
76+
protected String applicationPath() {
77+
return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString());
78+
}
79+
80+
@Override
81+
public String getOperationPath(String operationPath) {
82+
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/");
83+
return Paths.removeAdjacentForwardSlashes(
84+
uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString());
85+
}
86+
}
87+
5988
}

samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/AnotherFakeApiController.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package org.openapitools.api;
22

33
import org.springframework.stereotype.Controller;
4+
import org.springframework.web.bind.annotation.RequestMapping;
45
import org.springframework.web.context.request.NativeWebRequest;
56
import java.util.Optional;
67

78
@Controller
9+
@RequestMapping("${openapi.openAPIPetstore.base-path:/}")
810
public class AnotherFakeApiController implements AnotherFakeApi {
911

1012
private final NativeWebRequest request;

samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeApiController.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package org.openapitools.api;
22

33
import org.springframework.stereotype.Controller;
4+
import org.springframework.web.bind.annotation.RequestMapping;
45
import org.springframework.web.context.request.NativeWebRequest;
56
import java.util.Optional;
67

78
@Controller
9+
@RequestMapping("${openapi.openAPIPetstore.base-path:/}")
810
public class FakeApiController implements FakeApi {
911

1012
private final NativeWebRequest request;

0 commit comments

Comments
 (0)