Skip to content

Commit 6e3b199

Browse files
authored
[java][spring] add useSpringBuiltInValidation option to disable @validated at class level (fix #20899) (#20901)
* [java][spring] add useSpringBuiltInValidation option to disable @validated at class level (fix #20899) * Add sample and github workflow maintenance.
1 parent a4072c5 commit 6e3b199

File tree

83 files changed

+13447
-7
lines changed

Some content is hidden

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

83 files changed

+13447
-7
lines changed

.github/workflows/samples-spring.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ jobs:
4545
- samples/server/petstore/spring-boot-defaultInterface-unhandledException
4646
- samples/server/petstore/springboot
4747
- samples/server/petstore/springboot-beanvalidation
48+
- samples/server/petstore/springboot-builtin-validation
4849
- samples/server/petstore/springboot-delegate
4950
- samples/server/petstore/springboot-delegate-no-response-entity
5051
- samples/server/petstore/springboot-implicitHeaders
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
generatorName: spring
2+
outputDir: samples/server/petstore/springboot-builtin-validation
3+
library: spring-boot
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/spring/petstore-with-fake-endpoints-models-for-testing.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/JavaSpring
6+
additionalProperties:
7+
documentationProvider: springfox
8+
useSwaggerUI: false
9+
java8: true
10+
useBeanValidation: true
11+
useSpringBuiltInValidation: true
12+
artifactId: spring-boot-builtin-validation
13+
hideGenerationTimestamp: "true"

docs/generators/java-camel.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
106106
|useResponseEntity|Use the `ResponseEntity` type to wrap return values of generated API methods. If disabled, method are annotated using a `@ResponseStatus` annotation, which has the status of the first response declared in the Api definition| |true|
107107
|useSealed|Whether to generate sealed model interfaces and classes| |false|
108108
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
109+
|useSpringBuiltInValidation|Disable `@Validated` at the class level when using built-in validation.| |false|
109110
|useSpringController|Annotate the generated API as a Spring Controller| |false|
110111
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
111112
|useTags|use tags for creating interface and controller classnames| |false|

docs/generators/spring.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
9999
|useResponseEntity|Use the `ResponseEntity` type to wrap return values of generated API methods. If disabled, method are annotated using a `@ResponseStatus` annotation, which has the status of the first response declared in the Api definition| |true|
100100
|useSealed|Whether to generate sealed model interfaces and classes| |false|
101101
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
102+
|useSpringBuiltInValidation|Disable `@Validated` at the class level when using built-in validation.| |false|
102103
|useSpringController|Annotate the generated API as a Spring Controller| |false|
103104
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
104105
|useTags|use tags for creating interface and controller classnames| |false|

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public class SpringCodegen extends AbstractJavaCodegen
9696
public static final String USE_REQUEST_MAPPING_ON_INTERFACE = "useRequestMappingOnInterface";
9797
public static final String USE_SEALED = "useSealed";
9898
public static final String OPTIONAL_ACCEPT_NULLABLE = "optionalAcceptNullable";
99+
public static final String USE_SPRING_BUILT_IN_VALIDATION = "useSpringBuiltInValidation";
99100

100101
@Getter
101102
public enum RequestMappingMode {
@@ -152,6 +153,8 @@ public enum RequestMappingMode {
152153
protected RequestMappingMode requestMappingMode = RequestMappingMode.controller;
153154
@Getter @Setter
154155
protected boolean optionalAcceptNullable = true;
156+
@Getter @Setter
157+
protected boolean useSpringBuiltInValidation = false;
155158

156159
public SpringCodegen() {
157160
super();
@@ -214,6 +217,9 @@ public SpringCodegen() {
214217
CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames", useTags));
215218
cliOptions
216219
.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations", useBeanValidation));
220+
cliOptions.add(CliOption.newBoolean(USE_SPRING_BUILT_IN_VALIDATION,
221+
"Disable `@Validated` at the class level when using built-in validation.",
222+
useSpringBuiltInValidation));
217223
cliOptions.add(CliOption.newBoolean(PERFORM_BEANVALIDATION,
218224
"Use Bean Validation Impl. to perform BeanValidation", performBeanValidation));
219225
cliOptions.add(CliOption.newBoolean(USE_SEALED,
@@ -423,6 +429,7 @@ public void processOpts() {
423429
convertPropertyToBooleanAndWriteBack(UNHANDLED_EXCEPTION_HANDLING, this::setUnhandledException);
424430
convertPropertyToBooleanAndWriteBack(USE_RESPONSE_ENTITY, this::setUseResponseEntity);
425431
convertPropertyToBooleanAndWriteBack(OPTIONAL_ACCEPT_NULLABLE, this::setOptionalAcceptNullable);
432+
convertPropertyToBooleanAndWriteBack(USE_SPRING_BUILT_IN_VALIDATION, this::setUseSpringBuiltInValidation);
426433

427434
additionalProperties.put("springHttpStatus", new SpringHttpStatusLambda());
428435

@@ -623,6 +630,17 @@ public void processOpts() {
623630
modelTemplateFiles.clear();
624631
}
625632
supportsAdditionalPropertiesWithComposedSchema = true;
633+
634+
if (useBeanValidation) {
635+
if (additionalProperties.containsKey(USE_SPRING_BUILT_IN_VALIDATION)) {
636+
this.useSpringBuiltInValidation = Boolean.parseBoolean(
637+
additionalProperties.get(USE_SPRING_BUILT_IN_VALIDATION).toString()
638+
);
639+
} else {
640+
this.useSpringBuiltInValidation = false;
641+
}
642+
additionalProperties.put(USE_SPRING_BUILT_IN_VALIDATION, useSpringBuiltInValidation);
643+
}
626644
}
627645

628646
private boolean containsEnums() {

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ import org.springframework.http.HttpStatus;
3737
{{#useResponseEntity}}
3838
import org.springframework.http.ResponseEntity;
3939
{{/useResponseEntity}}
40-
{{#useBeanValidation}}
41-
import org.springframework.validation.annotation.Validated;
42-
{{/useBeanValidation}}
40+
{{#useBeanValidation}}{{^useSpringBuiltInValidation}}import org.springframework.validation.annotation.Validated;{{/useSpringBuiltInValidation}}{{/useBeanValidation}}
4341
{{#useSpringController}}
4442
{{#useResponseEntity}}
4543
import org.springframework.stereotype.Controller;
@@ -82,9 +80,7 @@ import java.util.concurrent.CompletableFuture;
8280
import {{javaxPackage}}.annotation.Generated;
8381

8482
{{>generatedAnnotation}}
85-
{{#useBeanValidation}}
86-
@Validated
87-
{{/useBeanValidation}}
83+
{{#useBeanValidation}}{{^useSpringBuiltInValidation}}@Validated{{/useSpringBuiltInValidation}}{{/useBeanValidation}}
8884
{{#useSpringController}}
8985
{{#useResponseEntity}}
9086
@Controller

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5383,4 +5383,53 @@ public void testEnumWithImplements() {
53835383

53845384
JavaFileAssert.assertThat(files.get("Type.java")).fileContains("Type implements java.io.Serializable {");
53855385
}
5386-
}
5386+
@Test
5387+
public void shouldEnableBuiltInValidationOptionWhenSetToTrue() throws IOException {
5388+
final SpringCodegen codegen = new SpringCodegen();
5389+
codegen.setUseSpringBoot3(true);
5390+
codegen.setUseOptional(true);
5391+
codegen.additionalProperties().put(SpringCodegen.USE_BEANVALIDATION, true);
5392+
codegen.additionalProperties().put(SpringCodegen.USE_SPRING_BUILT_IN_VALIDATION, true);
5393+
5394+
Map<String, File> files = generateFiles(codegen, "src/test/resources/3_0/petstore.yaml");
5395+
var file = files.get("UserApi.java");
5396+
5397+
JavaFileAssert.assertThat(file)
5398+
.hasNoImports("org.springframework.validation.annotation.Validated")
5399+
.assertTypeAnnotations()
5400+
.doesNotContainWithName("Validated");
5401+
}
5402+
5403+
@Test
5404+
public void shouldDisableBuiltInValidationOptionWhenSetToFalse() throws IOException {
5405+
final SpringCodegen codegen = new SpringCodegen();
5406+
codegen.setUseSpringBoot3(true);
5407+
codegen.setUseOptional(true);
5408+
codegen.additionalProperties().put(SpringCodegen.USE_BEANVALIDATION, true);
5409+
codegen.additionalProperties().put(SpringCodegen.USE_SPRING_BUILT_IN_VALIDATION, false);
5410+
5411+
Map<String, File> files = generateFiles(codegen, "src/test/resources/3_0/petstore.yaml");
5412+
var file = files.get("UserApi.java");
5413+
5414+
JavaFileAssert.assertThat(file)
5415+
.hasImports("org.springframework.validation.annotation.Validated")
5416+
.assertTypeAnnotations()
5417+
.containsWithName("Validated");
5418+
}
5419+
5420+
@Test
5421+
public void shouldDisableBuiltInValidationOptionByDefault() throws IOException {
5422+
final SpringCodegen codegen = new SpringCodegen();
5423+
codegen.setUseSpringBoot3(true);
5424+
codegen.setUseOptional(true);
5425+
codegen.additionalProperties().put(SpringCodegen.USE_BEANVALIDATION, true);
5426+
5427+
Map<String, File> files = generateFiles(codegen, "src/test/resources/3_0/petstore.yaml");
5428+
var file = files.get("UserApi.java");
5429+
5430+
JavaFileAssert.assertThat(file)
5431+
.hasImports("org.springframework.validation.annotation.Validated")
5432+
.assertTypeAnnotations()
5433+
.containsWithName("Validated");
5434+
}
5435+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
README.md
2+
pom.xml
3+
src/main/java/org/openapitools/OpenApiGeneratorApplication.java
4+
src/main/java/org/openapitools/RFC3339DateFormat.java
5+
src/main/java/org/openapitools/api/AnotherFakeApi.java
6+
src/main/java/org/openapitools/api/ApiUtil.java
7+
src/main/java/org/openapitools/api/FakeApi.java
8+
src/main/java/org/openapitools/api/FakeClassnameTestApi.java
9+
src/main/java/org/openapitools/api/PetApi.java
10+
src/main/java/org/openapitools/api/StoreApi.java
11+
src/main/java/org/openapitools/api/UserApi.java
12+
src/main/java/org/openapitools/configuration/EnumConverterConfiguration.java
13+
src/main/java/org/openapitools/configuration/HomeController.java
14+
src/main/java/org/openapitools/configuration/SpringFoxConfiguration.java
15+
src/main/java/org/openapitools/model/AdditionalPropertiesAnyType.java
16+
src/main/java/org/openapitools/model/AdditionalPropertiesArray.java
17+
src/main/java/org/openapitools/model/AdditionalPropertiesBoolean.java
18+
src/main/java/org/openapitools/model/AdditionalPropertiesClass.java
19+
src/main/java/org/openapitools/model/AdditionalPropertiesInteger.java
20+
src/main/java/org/openapitools/model/AdditionalPropertiesNumber.java
21+
src/main/java/org/openapitools/model/AdditionalPropertiesObject.java
22+
src/main/java/org/openapitools/model/AdditionalPropertiesString.java
23+
src/main/java/org/openapitools/model/Animal.java
24+
src/main/java/org/openapitools/model/ArrayOfArrayOfNumberOnly.java
25+
src/main/java/org/openapitools/model/ArrayOfNumberOnly.java
26+
src/main/java/org/openapitools/model/ArrayTest.java
27+
src/main/java/org/openapitools/model/BigCat.java
28+
src/main/java/org/openapitools/model/Capitalization.java
29+
src/main/java/org/openapitools/model/Cat.java
30+
src/main/java/org/openapitools/model/Category.java
31+
src/main/java/org/openapitools/model/ChildWithNullable.java
32+
src/main/java/org/openapitools/model/ClassModel.java
33+
src/main/java/org/openapitools/model/Client.java
34+
src/main/java/org/openapitools/model/ContainerDefaultValue.java
35+
src/main/java/org/openapitools/model/Dog.java
36+
src/main/java/org/openapitools/model/EnumArrays.java
37+
src/main/java/org/openapitools/model/EnumClass.java
38+
src/main/java/org/openapitools/model/EnumTest.java
39+
src/main/java/org/openapitools/model/File.java
40+
src/main/java/org/openapitools/model/FileSchemaTestClass.java
41+
src/main/java/org/openapitools/model/FormatTest.java
42+
src/main/java/org/openapitools/model/HasOnlyReadOnly.java
43+
src/main/java/org/openapitools/model/MapTest.java
44+
src/main/java/org/openapitools/model/MixedPropertiesAndAdditionalPropertiesClass.java
45+
src/main/java/org/openapitools/model/Model200Response.java
46+
src/main/java/org/openapitools/model/ModelApiResponse.java
47+
src/main/java/org/openapitools/model/ModelList.java
48+
src/main/java/org/openapitools/model/ModelReturn.java
49+
src/main/java/org/openapitools/model/Name.java
50+
src/main/java/org/openapitools/model/NullableMapProperty.java
51+
src/main/java/org/openapitools/model/NumberOnly.java
52+
src/main/java/org/openapitools/model/Order.java
53+
src/main/java/org/openapitools/model/OuterComposite.java
54+
src/main/java/org/openapitools/model/OuterEnum.java
55+
src/main/java/org/openapitools/model/ParentWithNullable.java
56+
src/main/java/org/openapitools/model/Pet.java
57+
src/main/java/org/openapitools/model/ReadOnlyFirst.java
58+
src/main/java/org/openapitools/model/ResponseObjectWithDifferentFieldNames.java
59+
src/main/java/org/openapitools/model/SpecialModelName.java
60+
src/main/java/org/openapitools/model/Tag.java
61+
src/main/java/org/openapitools/model/TypeHolderDefault.java
62+
src/main/java/org/openapitools/model/TypeHolderExample.java
63+
src/main/java/org/openapitools/model/User.java
64+
src/main/java/org/openapitools/model/XmlItem.java
65+
src/main/resources/application.properties
66+
src/main/resources/openapi.yaml
67+
src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7.13.0-SNAPSHOT

0 commit comments

Comments
 (0)