Spring Validation TypeMismatch如何自定义defaultMessage

时间:2018-12-11 11:32:23

标签: spring-boot

我有一个用户实体,我想将年龄验证为整数,但是如果我将输入年龄键入为字符串,例如“ dawdawdawdawdawdawdawdwa”。我从bindingResult得到一个错误

[
{
    "codes": [
        "typeMismatch.user.age",
        "typeMismatch.age",
        "typeMismatch.java.lang.Integer",
        "typeMismatch"
    ],
    "arguments": [
        {
            "codes": [
                "user.age",
                "age"
            ],
            "arguments": null,
            "defaultMessage": "age",
            "code": "age"
        }
    ],
    "defaultMessage": "Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' for property 'age'; nested exception is java.lang.NumberFormatException: For input string: \"dawdawdawdawdawdawdawdwa\"",
    "objectName": "user",
    "field": "age",
    "rejectedValue": "dawdawdawdawdawdawdawdwa",
    "bindingFailure": true,
    "code": "typeMismatch"
}
]

这是用户实体

@Entity
@Table(name="users")
@Data
@JsonIdentityInfo(
    generator = ObjectIdGenerators.PropertyGenerator.class,
    property = "id")
public class User implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;

@Column(name = "name")
@ApiModelProperty(notes="Name should have atleast 2 characters, max 5 characters")
@Size(min=2, max = 5, message="Name should have atleast 2 characters, max 5 characters")
private String name;


@Column(name = "age")
@Digits(integer=2, fraction=0, message = "Age is a only numeric")
private Integer age; 

}

控制器

@PostMapping(value = "")
public List store(@Valid User user, BindingResult bindingResult) throws Exception {
    if (bindingResult.hasErrors()) {
        return bindingResult.getFieldErrors();
    }
    return bindingResult.getFieldErrors();
}

问题是defaultMessage响应“无法将类型'java.lang.String'的属性值转换为属性'age'的必需类型'java.lang.Integer';嵌套异常...”

但是我想看到defaultMessage是我在上面的代码中定义的“ 年龄是唯一的数字”。

@Column(name = "age")
@Digits(integer=2, fraction=0, message = "Age is a only numeric")
private Integer age; 

1 个答案:

答案 0 :(得分:0)

我将为用户类实现一个验证器:

public class UserValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return User.class.equals(clazz);
    }

    public void validate(Object userToValidate, Errors e) {
        User user = (User) userToValidate;

        // Validate the name
        ValidationUtils.rejectIfEmptyOrWhitespace(...);

        // Validate the age
        if (age not a number) {
            e.rejectValue("age", "age.nan", "Age is a only numeric");
        }

        // Some more validations here
    }
}

之后,您创建一个UserValidationException-Class:

public class UserValidationException extends RunetimeException {
    private Errors errors;
    private String message;
    private String field;

    // maybe more info

    // logic here
}

之后,您可以使用@ControllerAdvice注释实现ExceptionHandler:

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(UserValidationException.class)
    protected ResponseEntity<Object> handleUserValidationException(final UservalidationException uve) {
        return new ResponseEntity<Object>(uve.getErrors().getAllErrors(), HttpStatus.BAD_REQUEST);


    // more exceptionHandlers: for example: UserNotFoundException....

    }

}

最后在Controller中执行验证:

public List store(...) {

    Errors errors = new BindException(user, "user");
    ValidationUtils.invokeValidator(new UserValidator(), user, errors);
    if (errors.hasErrors()) {
        throw new UserValidationException(errors);
    }
} 

这样,您可以进行清晰的验证

一些信息:https://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/validation.html https://medium.com/@jovannypcg/understanding-springs-controlleradvice-cd96a364033f 不同的Spring验证教程