首页 > 解决方案 > 每个请求的 Spring Boot REST 验证都失败

问题描述

我已经在 REST Spring Boot API 中实现了请求验证。

这是请求模型:

@Data
@ApiModel
public class ConfirmUserTokenRequest {
    @Min(3)
    @Max(25)
    @NotBlank
    private String firstName;

    @Min(3)
    @Max(25)
    @NotBlank
    private String lastName;

    @Email
    @NotBlank
    private String email;

    @Min(3)
    @Max(50)
    private String companyName;

    @ApiModelProperty(value = "Usage purpose", allowableValues = "SEO, CRAWLING, BLOGGING, DEVOPS, OTHER")
    private String usagePurpose;

    @Min(2)
    @Max(2)
    @ApiModelProperty(value = "ISO Alpha-2 country code of user", example = "US")
    private String countryCode;

    @Min(6)
    @Max(30)
    @NotBlank
    private String password;

    @NotBlank
    private String redirectUri;

    private String data;
}

In the controller method, I have validated the request body parameter with *@Valid* annotation to turn on validation.

这是控制器方法定义:

@PostMapping
@ResponseStatus(HttpStatus.NO_CONTENT)
public ResponseEntity<Object> createToken(@Valid @RequestBody ConfirmUserTokenRequest confirmUserTokenRequest)

这是控制器建议处理验证异常:

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers, HttpStatus status,
                                                                  WebRequest request) {
        List<String> errors = new ArrayList<>();
        for (FieldError error : ex.getBindingResult().getFieldErrors()) {
            errors.add(error.getField() + ": " + error.getDefaultMessage());
        }
        for (ObjectError error : ex.getBindingResult().getGlobalErrors()) {
            errors.add(error.getObjectName() + ": " + error.getDefaultMessage());
        }
        APIError apiError = new APIError( "Validation failed", errors);
        return new ResponseEntity<>(apiError, HttpStatus.BAD_REQUEST);
    }

即使对于看似有效的请求,也会引发验证异常:例如,以下请求会给出验证错误:

POST /no-auth/manager/token/confirm-user HTTP/1.1

Host: 127.0.0.1:8080
Content-Type: application/json
cache-control: no-cache
{
"firstName": "John",
"lastName": "Doe",
"email": "gayeta@example.com",
"countryCode": "AU",
"companyName": "Galaxy Corp",
"usagePurpose": "SEO",
"password": "init@test",
"data": null,
"redirectUri": "http://127.0.0.1:8080/callback/confirm-user"
}

我收到以下验证错误:

{
    "timestamp": "2019-01-09T06:54:56.635",
    "message": "Validation failed",
    "errors": [
        "companyName: must be greater than or equal to 3",
        "password: must be less than or equal to 30",
        "lastName: must be less than or equal to 25",
        "firstName: must be less than or equal to 25",
        "lastName: must be greater than or equal to 3",
        "password: must be greater than or equal to 6",
        "firstName: must be greater than or equal to 3",
        "companyName: must be less than or equal to 50"
     ]
}

即使对于这个看似有效的请求,也会引发错误。出了什么问题?

标签: spring-boot

解决方案


而不是单独使用@Min& @Max,尝试@Size(min = 2, max = 25).

此外,如果您已申请@Min,则无需@NotBlank将其更改为@NotNull

@Min@Max用于验证 int、short、byte 等数字字段及其各自的原始包装器。

@Size用于检查字段的长度限制。

根据文档,@Size支持 String、Collection、Map 和数组,同时@Min支持@Max原语及其包装器。


推荐阅读