如果是参数类型不匹配,会得到:
{ "timestamp": 1530955359265, "status": 400, "error": "Bad Request", "exception": "org.springframework.validation.BindException", "errors": [ { "codes": [ "typeMismatch.formRequest.age", "typeMismatch.age", "typeMismatch.int", "typeMismatch" ], "arguments": [ { "codes": [ "formRequest.age", "age" ], "arguments": null, "defaultMessage": "age", "code": "age" } ], "defaultMessage": "Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'age'; nested exception is java.lang.NumberFormatException: For input string: \"\"", "objectName": "formRequest", "field": "age", "rejectedValue": "", "bindingFailure": true, "code": "typeMismatch" } ], "message": "Validation failed for object='formRequest'. Error count: 1", "path": "/validate/form" }Form表单参数上,使用@Valid注解可达到同样目的,而关于两者的区别则是:
@Valid 基于JSR303,即 Bean Validation 1.0,由Hibernate Validator实现;
@Validated 基于JSR349,是Bean Validation 1.1,由Spring框架扩展实现;
后者做了一些增强扩展,如支持分组校验,有兴趣可参考这里。
四、RequestBody 校验对于直接Json消息体输入,同样可以定义校验规则:
@PostMapping("/json") @ResponseBody public JsonRequest json(@Validated @RequestBody JsonRequest request) { return request; } ... public static class JsonRequest { @NotEmpty @Email private String email; @Pattern(regexp = "[a-zA-Z0-9_]{6,30}") private String name; @Min(5) @Max(199) private int age;校验异常
构造一个违反规则的Json请求体进行输入,会得到:
此时与FormBinding的情况不同,我们得到了一个MethodArgumentNotValidException异常。
而如果发生参数类型不匹配,比如输入age=1f,会产生以下结果:
这表明在JSON转换过程中已经失败!
五、自定义校验规则框架内预置的校验规则可以满足大多数场景使用,
但某些特殊情况下,你需要制作自己的校验规则,这需要用到ContraintValidator接口。
我们以一个密码校验的场景作为示例,比如一个注册表单上,
我们需要检查 密码输入 与 密码确认 是一致的。
**首先定义 PasswordEquals 注解
@Documented @Constraint(validatedBy = { PasswordEqualsValidator.class }) @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface PasswordEquals { String message() default "Password is not the same"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }在表单上声明@PasswordEquals 注解
@PasswordEquals public class RegisterForm { @NotEmpty @Length(min=5,max=30) private String username; @NotEmpty private String password; @NotEmpty private String passwordConfirm;