1. 概述
當我們想要使用 Swagger 生成驗證時,我們通常使用 基本規範。但是,我們可能需要添加 Spring 自定義驗證註解。
本教程將教你如何使用這些驗證生成模型和 REST API,重點關注 OpenAPI 服務器生成器,而不是約束驗證器。
2. 設置
為了設置,我們將使用一篇之前的 Baeldung 教程,從 OpenAPI 3.0.0 定義生成一個服務器。接下來,我們將添加一些自定義驗證註解,以及所有需要的依賴項。
3. 寵物商店 API OpenAPI 定義
假設我們有一個寵物商店 API 的 OpenAPI 定義,並且需要為 REST API 和描述的模型,Pet,添加自定義驗證。
3.1. API 模型的自定義驗證
為了創建寵物,我們需要讓 Swagger 使用我們的自定義驗證註解來測試寵物名稱是否大寫。作為本教程的目的,我們將簡單地將其稱為Capitalized。
請觀察下面x-constraints規範。只需讓 Swagger 知道我們需要生成另一種類型的註解即可:
openapi: 3.0.1
info:
version: "1.0"
title: PetStore
paths:
/pets:
post:
#.. post described here
components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
x-constraints: "Capitalized(required = true)"
tag:
type: string
3.2. REST API 端點的自定義驗證
如上所述,我們將以相同的方式描述一個按寵物名稱查找所有寵物的端點。為了演示我們的目的,假設我們的系統區分大小寫,因此我們將再次為name輸入參數添加x-constraints驗證:
/pets:
# post defined here
get:
tags:
- pet
summary: Finds Pets by name
description: 'Find pets by name'
operationId: findPetsByTags
parameters:
- name: name
in: query
schema:
type: string
description: Tags to filter by
required: true
x-constraints: "Capitalized(required = true)"
responses:
'200':
description: default response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid tag value
4. 創建 大寫 註解
為了強制自定義驗證,我們需要創建一個註解,以確保功能的正確性。
首先,我們創建註解接口 – @Capitalized:
@Documented
@Constraint(validatedBy = {Capitalized.class})
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Capitalized{
String message() default "Name should be capitalized.";
boolean required() default true;
// default annotation methods
}
請注意,我們為演示目的創建了 必需 方法 – 我們稍後會解釋這個方法。
接下來,我們添加 CapitalizedValidator,該驗證器在上述 @Constraint 註解中引用。
public class CapitalizedValidator implements ConstraintValidator<Capitalized, String> {
@Override
public boolean isValid(String nameField, ConstraintValidatorContext context) {
// validation code here
}
}
5. 生成驗證註釋
5.1. 指定Mustache模板目錄
要生成帶有 @Capitalized 驗證註釋的模型,我們需要特定的Mustache模板,讓Swagger在模型中生成它。
因此,在OpenAPI生成插件中,在<configuration>[..]</configuration>標籤中,我們需要添加一個模板目錄:
<plugin>
//...
<executions>
<execution>
<configuration
//...
<templateDirectory>
${project.basedir}/src/main/resources/openapi/templates
</templateDirectory>
//...
</configuration>
</execution>
</executions>
//...
</plugin>
5.2. 添加Mustache Bean 驗證配置
在本章中,我們將配置Mustache模板以生成驗證規範。為了添加更多細節,我們將修改<a href="https://raw.githubusercontent.com/swagger-api/swagger-codegen/master/modules/swagger-codegen/src/main/resources/Java/beanValidationCore.mustache">beanValidationCore.mustachemodel.mustacheapi.muctache
首先,我們需要修改<a href="https://raw.githubusercontent.com/swagger-api/swagger-codegen/master/modules/swagger-codegen/src/main/resources/Java/beanValidationCore.mustache">beanValidationCore.mustache
{{{ vendorExtensions.x-constraints }}}
其次,如果我們的註解具有嵌套屬性,例如<em title="Capitalized">(required = “true”)beanValidationCore.mustache
{{#required}}@Capitalized(required="{{{pattern}}}") {{/required}}
第三,我們需要修改<a href="https://github.com/swagger-api/swagger-codegen/blob/master/modules/swagger-codegen/src/main/resources/Java/model.mustache">model.mustachemodel.mustache
{{#imports}}import {{import}}; {{/imports}} import
com.baeldung.openapi.petstore.validator.CapitalizedValidator;
import com.baeldung.openapi.petstore.validator.Capitalized;
最後,為了在API中生成註釋,我們需要在<a href="https://github.com/swagger-api/swagger-codegen/blob/master/modules/swagger-codegen/src/main/resources/Java/api.mustache">api.mustache
{{#imports}}import {{import}}; {{/imports}} import
com.baeldung.openapi.petstore.validator.Capitalized;
此外,<a href="https://github.com/swagger-api/swagger-codegen/blob/master/modules/swagger-codegen/src/main/resources/Java/api.mustache">api.mustachecookieParams.mustache
6. 生成源文件
為了完成工作,我們可以使用生成的代碼。我們需要運行,至少需要 mvn generate-sources>。這將生成模型:
public class Pet {
@JsonProperty("id")
private Long id = null;
@JsonProperty("name")
private String name = null;
// 其他參數
@Schema(required = true, description = "")
@Capitalized public String getName() { return name; } // 默認獲取器和設置器
它還會生成一個 API:
default ResponseEntity<List<Pet>> findPetsByTags(
@Capitalized(required = true)
@ApiParam(value = "Tags to filter by")
@Valid @RequestParam(value = "name", required = false) String name) {
// 默認生成的代碼在此
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
7. 測試使用 curl
啓動應用程序後,我們將運行一些 curl 命令來測試它。
此外,請注意,約束違反也會拋出 ConstraintViolationException。 異常需要通過 @ControllerAdvice 適當處理,以返回 400 Bad Request 狀態。
7.1. 測試 Pet 模型驗證
此 Pet 模型具有小寫的 name。 因此,應用程序應返回 400 Bad Request:
curl -X 'POST' \
'http://localhost:8080/pet' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": 1,
"name": "rockie"
}'
7.2. 測試 Find Pet API
與上述相同的方式,因為 name 是小寫的,應用程序也應返回 400 Bad Request:
curl -I http://localhost:8080/pets/name="rockie"
8. 結論
在本教程中,我們學習瞭如何使用 Spring 生成自定義約束驗證器,同時實現 REST API 服務器。