如何在Swagger Codegen中注入自定义Spring校验注解生成输入类?
Great question! While Swagger Codegen handles standard JSR-380 validation annotations (like @NotNull, @Size) out of the box, adding custom Spring @Constraint annotations requires a lightweight, maintainable combination of OpenAPI vendor extensions and template customization. Here's the optimal approach:
1. Annotate Your OpenAPI Spec with Custom Validation Metadata
First, use OpenAPI vendor extensions (prefixed with x-) to map your custom constraints to schema properties. This keeps your API spec as the single source of truth for both API structure and validation rules.
For example, if you have a custom @ValidPhoneNumber annotation and a parameterized @ValidUserId annotation:
components: schemas: User: type: object properties: phoneNumber: type: string x-custom-validation: "@ValidPhoneNumber" userId: type: string x-custom-validation: "@ValidUserId(prefix = 'US')" email: type: string format: email x-custom-validation: "@ValidCorporateEmail"
If you prefer a more structured approach (instead of raw annotation strings), you can define extension keys for specific constraints:
phoneNumber: type: string x-valid-phone-number: true
2. Customize the Swagger Codegen Template
Swagger Codegen uses Mustache templates to generate classes. You'll modify the model template to inject your custom annotations based on the extensions above.
Step 2.1: Extract the Default Template
First, get the default model.mustache template for the Spring generator. You can extract it from the codegen CLI jar:
unzip swagger-codegen-cli.jar -d temp-codegen-files cp temp-codegen-files/resources/JavaSpring/model.mustache ./custom-templates/
Step 2.2: Modify the Template to Render Custom Annotations
Open the custom-templates/model.mustache file, find the section where field annotations are added (right above the field declaration), and add logic to render your custom annotations.
For raw annotation strings (using x-custom-validation):
{{#isNotNull}} @NotNull{{#requiredAnnotationMessage}}(message = "{{requiredAnnotationMessage}}"){{/requiredAnnotationMessage}} {{/isNotNull}} {{#minLength}} @Size(min = {{minLength}}){{#minLengthAnnotationMessage}}(message = "{{minLengthAnnotationMessage}}"){{/minLengthAnnotationMessage}} {{/minLength}} <!-- Add custom validation annotations here --> {{#vendorExtensions.x-custom-validation}} {{.}} {{/vendorExtensions.x-custom-validation}} private {{datatype}} {{name}};
For structured extension keys (like x-valid-phone-number):
{{#vendorExtensions.x-valid-phone-number}} @ValidPhoneNumber {{/vendorExtensions.x-valid-phone-number}} {{#vendorExtensions.x-valid-corporate-email}} @ValidCorporateEmail {{/vendorExtensions.x-valid-corporate-email}}
3. Run Codegen with Custom Templates
Execute the codegen CLI, specifying your custom template directory with the -t flag:
java -jar swagger-codegen-cli.jar generate \ -i your-openapi-spec.yaml \ -l spring \ -o generated-spring-code \ -t ./custom-templates/
4. Ensure Dependencies Are Available
Make sure your generated code has access to your custom validation annotations and their corresponding validators. Add the dependency to your project's build file:
<!-- pom.xml example --> <dependency> <groupId>com.yourcompany</groupId> <artifactId>custom-validation-lib</artifactId> <version>1.0.0</version> </dependency>
Is There an "Out-of-the-Box" Solution?
Since custom @Constraint annotations are project-specific, there's no universal built-in support in Swagger Codegen. However, the approach above is the official, recommended way to extend the generator—it's lightweight, maintainable, and keeps your API spec in control.
If you need even more flexibility (like dynamic annotation generation based on complex rules), you could write a custom Codegen class, but that's overkill for most use cases. The template + vendor extension method is the sweet spot.
内容的提问来源于stack exchange,提问作者sa_vedem




