diff --git a/docs/generators/spring.md b/docs/generators/spring.md index eed7875d2273..58518b6c658e 100644 --- a/docs/generators/spring.md +++ b/docs/generators/spring.md @@ -61,4 +61,5 @@ sidebar_label: spring |useOptional|Use Optional container for optional parameters| |false| |hateoas|Use Spring HATEOAS library to allow adding HATEOAS links| |false| |returnSuccessCode|Generated server returns 2xx code| |false| +|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).|false| |library|library template (sub-template)|
**spring-boot**
Spring-boot Server application using the SpringFox integration.
**spring-mvc**
Spring-MVC Server application using the SpringFox integration.
**spring-cloud**
Spring-Cloud-Feign client with Spring-Boot auto-configured settings.
|spring-boot| 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 4e2c694fd8be..0946fc271c1b 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 @@ -66,6 +66,7 @@ public class SpringCodegen extends AbstractJavaCodegen public static final String API_FIRST = "apiFirst"; public static final String HATEOAS = "hateoas"; public static final String RETURN_SUCCESS_CODE = "returnSuccessCode"; + public static final String UNHANDLED_EXCEPTION_HANDLING = "unhandledException"; protected String title = "OpenAPI Spring"; protected String configPackage = "org.openapitools.configuration"; @@ -88,6 +89,7 @@ public class SpringCodegen extends AbstractJavaCodegen protected boolean virtualService = false; protected boolean hateoas = false; protected boolean returnSuccessCode = false; + protected boolean unhandledException = false; public SpringCodegen() { super(); @@ -130,6 +132,7 @@ public SpringCodegen() { cliOptions.add(CliOption.newBoolean(USE_OPTIONAL,"Use Optional container for optional parameters", useOptional)); cliOptions.add(CliOption.newBoolean(HATEOAS, "Use Spring HATEOAS library to allow adding HATEOAS links", hateoas)); cliOptions.add(CliOption.newBoolean(RETURN_SUCCESS_CODE, "Generated server returns 2xx code", returnSuccessCode)); + cliOptions.add(CliOption.newBoolean(UNHANDLED_EXCEPTION_HANDLING, "Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).", unhandledException)); supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application using the SpringFox integration."); supportedLibraries.put(SPRING_MVC_LIBRARY, "Spring-MVC Server application using the SpringFox integration."); @@ -286,6 +289,12 @@ public void processOpts() { this.setReturnSuccessCode(Boolean.valueOf(additionalProperties.get(RETURN_SUCCESS_CODE).toString())); } + if (additionalProperties.containsKey(UNHANDLED_EXCEPTION_HANDLING)) { + this.setUnhandledException(Boolean.valueOf(additionalProperties.get(UNHANDLED_EXCEPTION_HANDLING).toString())); + } else { + additionalProperties.put(UNHANDLED_EXCEPTION_HANDLING, this.isUnhandledException()); + } + typeMapping.put("file", "Resource"); importMapping.put("Resource", "org.springframework.core.io.Resource"); @@ -687,6 +696,10 @@ public String getConfigPackage() { return this.configPackage; } + public boolean isUnhandledException() { + return unhandledException; + } + public void setBasePackage(String basePackage) { this.basePackage = basePackage; } @@ -737,6 +750,10 @@ public void setReturnSuccessCode(boolean returnSuccessCode) { this.returnSuccessCode = returnSuccessCode; } + public void setUnhandledException(boolean unhandledException) { + this.unhandledException = unhandledException; + } + @Override public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { super.postProcessModelProperty(model, property); diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache index e42ba2aca1b3..c1c1d9ab86ec 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache @@ -109,7 +109,7 @@ public interface {{classname}} { produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}{{#hasConsumes}} consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}{{/singleContentTypes}} method = RequestMethod.{{httpMethod}}) - {{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{^hasMore}}{{#reactive}}, {{/reactive}}{{/hasMore}}{{/allParams}}{{#reactive}}ServerWebExchange exchange{{/reactive}}){{^jdk8}};{{/jdk8}}{{#jdk8}} { + {{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{^hasMore}}{{#reactive}}, {{/reactive}}{{/hasMore}}{{/allParams}}{{#reactive}}ServerWebExchange exchange{{/reactive}}){{^jdk8}};{{/jdk8}}{{#jdk8}}{{#unhandledException}} throws Exception{{/unhandledException}} { {{#delegate-method}} return {{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}); } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index f9dec31da461..40cf357b4425 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -67,6 +67,7 @@ public void testInitialConfigValues() throws Exception { Assert.assertEquals(codegen.getConfigPackage(), "org.openapitools.configuration"); Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.CONFIG_PACKAGE), "org.openapitools.configuration"); Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.SERVER_PORT), "8082"); + Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.UNHANDLED_EXCEPTION_HANDLING), false); } @Test @@ -78,6 +79,7 @@ public void testSettersForConfigValues() throws Exception { codegen.setInvokerPackage("xx.yyyyyyyy.invoker"); codegen.setBasePackage("xx.yyyyyyyy.base"); codegen.setConfigPackage("xx.yyyyyyyy.config"); + codegen.setUnhandledException(true); codegen.processOpts(); Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.TRUE); @@ -92,6 +94,8 @@ public void testSettersForConfigValues() throws Exception { Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.BASE_PACKAGE), "xx.yyyyyyyy.base"); Assert.assertEquals(codegen.getConfigPackage(), "xx.yyyyyyyy.config"); Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.CONFIG_PACKAGE), "xx.yyyyyyyy.config"); + Assert.assertEquals(codegen.isUnhandledException(), true); + Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.UNHANDLED_EXCEPTION_HANDLING), true); } @Test