写在前面
本文基于springboot环境进行测试,如果还没有环境,可以参考这里。
1:系统自带验证
1.1:定义验证类
public class ValidatorPojo {
@NotNull(message = "id不能为空")
private Long id;
// 只能是将来的日期
@Future
@DateTimeFormat(pattern = "yyy-MM-dd")
@NotNull
private Date date;
@NotNull
// 最小值0.1
@DecimalMin(value = "0.1")
// 最大值10000
@DecimalMin(value = "10000.00")
private Double doubleValue = null;
// 最小值为1
@Min(value = 1, message = "最小值为1")
// 最大值为88
@Max(value = 88, message = "最大值为88")
// 不能为空
@NotNull
private Integer integer;
// 限定范围
@Range(min = 1, max = 888, message = "范围为1 至 888")
private Long range;
// 邮箱验证
@Email(message = "邮箱格式错误")
private String email;
@Size(min = 20, max = 30, message = "字符串长度要求20到30之间。")
private String size;
...getter setter tostring...
}
1.2:定义controller
@RequestMapping(value = "/valid/validate")
@ResponseBody
public Map<String, Object> validate(
@Valid @RequestBody ValidatorPojo vp,
Errors errors) {
Map<String, Object> errMap = new HashMap<>();
List<ObjectError> objectErrors = errors.getAllErrors();
for (ObjectError objectError : objectErrors) {
String key = null;
String msg = null;
if (objectError instanceof FieldError) {
FieldError fieldError = (FieldError) objectError;
key = fieldError.getField();
} else {
key = objectError.getObjectName();
}
// 错误信息
msg = objectError.getDefaultMessage();
errMap.put(key, msg);
}
return errMap;
}
1.3:测试
curl:
curl \
-H "Content-Type: application/json" \
-X POST \
-d '{"id": null, "date": "2017-08-08", "doubleValue": 999999.09, "integer": 100, "range": 1000, "email": "email", "size": "adv1212"," regexp": "a,b,c,d"}' \
http://localhost:9875//valid/validate
结果:
{
"date": "需要是一个将来的时间",
"size": "字符串长度要求20到30之间。",
"range": "范围为1 至 888",
"integer": "最大值为88",
"id": "id不能为空",
"email": "邮箱格式错误"
}
我本地请求测试:
xbdeMacBook-Air:~ xb$ curl \
> -H "Content-Type: application/json" \
> -X POST \
> -d '{"id": null, "date": "2017-08-08", "doubleValue": 999999.09, "integer": 100, "range": 1000, "email": "email", "size": "adv1212"," regexp": "a,b,c,d"}' \
> http://localhost:9875//valid/validate
{
"date":"需要是一个将来的时间","size":"字符串长度要求20到30之间。","range":"范围为1 至 888","integer":"最大值为88","id":"id不能为空","email":"邮箱格式错误"}
2:自定义验证器
自定义验证器只需要实现org.springframework.validation.Validator
接口,该接口源码如下:
public interface Validator {
// 验证是否支持验证指定类型
boolean supports(Class<?> clazz);
// 执行验证的方法
// 参数target是待验证的控制器接受参数
// 参数errors是错误信息,可以在控制器中接受
void validate(Object target, Errors errors);
}
但是仅仅定义后还不能被使用,还需要通过WebDataBinder机制进行设置,具体做法是在控制器中定义方法,然后使用注解@InitBinder
标注方法,其中WebDataBinder会被作为参数传递进去,然后就可以设置我们的自定义的验证器了,下面我们就开始吧!
2.1:自定义验证器
public class UserValidator implements Validator {
/**
* 判断是否支持验证的方法
* @param aClass 待验证对象类型
* @return 是否支持验证
*/
@Override
public boolean supports(Class<?> aClass) {
return aClass.equals(User.class);
}
/**
* 验证目标对象方法
* @param target 待验证的目标对象
* @param errors 错误信息,该对象可以在controller中使用
*/
@Override
public void validate(Object target, Errors errors) {
if (target == null) {
errors.rejectValue("", null, "用户不能为空");
return;
}
// 强转
User user = (User) target;
// 用户名非空串
if (StringUtils.isEmpty(user.getUserName())) {
errors.rejectValue("userName", null, "用户名不能为空");
}
}
}
2.2:注册验证器
/**
* 使用了@InitBinder会在进入控制器方法前调用该方法,
* 并将WebDataBinder作为参数传递过来
* @param binder
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
// 绑定我们自定义的验证器
binder.setValidator(new UserValidator());
}
2.3:数据模型对象
public class User {
private Long id;
private String userName;
...getter setter toString...
}
2.4:自定义转换器
因为本例参数接收需要使用到自定义转换器,所以需要定义出来,对转换器不清楚的可以移步这里。
@Component
public class MyStringToUserConverter implements Converter<String, User> {
@Override
public User convert(String source) {
User user = new User();
if (StringUtils.isEmpty(source)) return user;
String[] userFieldValArr = StringUtils.commaDelimitedListToStringArray(source);
int length = userFieldValArr.length;
if (length >= 1) {
user.setId(Long.valueOf(userFieldValArr[0]));
}
if (length >= 2) {
user.setUserName(userFieldValArr[1]);
}
return user;
}
}