下面主要是在 Controller 上进行校验。本模块进行了下面的 junit 单元测试
@RestController@RequestMapping("/validator")@Validatedpublic class ValidatorController {@RequestMapping("/para1")public Map para1(@RequestParam @Length(min = 6,max = 50) String name,@RequestParam @Valid @Email String email,@RequestParam String cellPhone) {return para(name,email,cellPhone);}@RequestMapping("/para2")@ResponseResultpublic Map para2(@RequestParam @Length(min = 6,max = 50) String name,@RequestParam @Email String email,@RequestParam String cellPhone) {return para(name,email,cellPhone);}private Map para(String name,String email,String cellPhone){String str= "name:"+name+";"+"email:"+email+";"+"cellPhone:"+cellPhone+";";return new HashMap<String,String>(){{put("para", str);}};}}
测试结果(没有加全局错误处理)
2018-03-10 12:26:37.656 ERROR 6524 --- [o-auto-1-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.validation.ConstraintViolationException: fail.name: 长度需要在6和50之间, fail.email: 不是一个合法的电子邮件地址] with root causejavax.validation.ConstraintViolationException: fail.name: 长度需要在6和50之间, fail.email: 不是一个合法的电子邮件地址
@Datapublic class City {@Range(min = 1, max = 20, message = "id只能从1-20")private int id;@Length(min = 6,max = 50)private String name;private String code;}
在 controller 类上,必须添加@Valid 才有作用
@Validated
@RequestMapping("/bean2")public City bean2(@RequestBody @Valid City city) {return bean(city);}
返回的错误信息例子
{"status": 400,"error": "Bad Request","message": "参数无效","code": 10001,"path": "/validator/bean2","exception": "org.springframework.web.bind.MethodArgumentNotValidException","errors": [{"fieldName": "id","message": "id只能从1-20"},{"fieldName": "name","message": "长度需要在6和50之间"}],"timestamp": "2018-03-12T03:34:09.653+0000"}
如果想强行捕获错误,进行处理,可以抛出错误,也可以不抛出错误。
在接口处@Validated 添加 BindingResult,可以在函数体内得到错误信息。
@RequestMapping("/method2")public String method2(@RequestBody @Validated City city,BindingResult result) {if(result.hasErrors()) {List<ObjectError> list = result.getAllErrors();for (ObjectError error : list) {System.out.println(error.getCode() + "---" + error.getArguments() + "---" + error.getDefaultMessage());}}return city.getName()+"ok";}
@Validated 与@Valid 是有区别的,建议用@Valid 直接抛出异常
在com.wukong.core.validator
中自己定义了phone
与url
两个自定义的方法。
public class PhoneValidator implements ConstraintValidator<Phone, String> {private Pattern pattern = Pattern.compile("1(([38]\\d)|(5[^4&&\\d])|(4[579])|(7[0135678]))\\d{8}");@Overridepublic void initialize(Phone phone){}@Overridepublic boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext){return pattern.matcher(value).matches();}}
常用 validator
名称 | 说明 | |
---|---|---|
@null | 验证对象是否为空 | |
@notnull | 验证对象是否为非空 | |
@asserttrue | 验证 boolean 对象是否为 true | |
@assertfalse | 验证 boolean 对象是否为 false | |
@min | 验证 number 和 string 对象是否大等于指定的值 | |
@max | 验证 number 和 string 对象是否小等于指定的值 | |
@decimalmin | 验证 number 和 string 对象是否大等于指定的值,小数存在精度 | |
@decimalmax | 验证 number 和 string 对象是否小等于指定的值,小数存在精度 | |
@size | 验证对象(array,collection,map,string)长度是否在给定的范围之内 | |
@digits | 验证 number 和 string 的构成是否合法 | |
@past | 验证 date 和 calendar 对象是否在当前时间之前 | |
@future | 验证 date 和 calendar 对象是否在当前时间之后 | |
@pattern | 验证 string 对象是否符合正则表达式的规则 | |
验证邮箱 |
例子说明(regexp 表达式比较好用)
例如:class 目录添加两个文件 。必须用 ValidationMessages 开头
ValidationMessages.properties
demo.name = 名字不能为空
ValidationMessages_en.properties
demo.name = name is not empty.
注解中加入{demo.name}
@NotEmpty(message="{demo.name}")