目录
简述:
Spring的参数校验:
程序基本框架:
创建一个DTO对象:
Controller程序:
发起请求:
打印结果:
增加校验
@Validated 注解:
@Validated 和 @Valid 区别
增加参数校验注解:
java validation注解
hibernate validation 注解
在Bean上增加需要校验的设置
自定义validation注解
定义注解
校验的实现
对于后台系统来讲,在入口处进行参数校验是非常必要的,这样可以减少后端的很多数据的判断,也可以减少大量的异常情况;
一个好的参数校验方法:顶一个一个实体类来封装请求参数,使用Spring的@Validated,结合java validation,hibernate validation注解进行校验
先创建程序基本框架,将一个前端的请求,转换成DTO对象;
public class testBO {
/**
* 姓名
*/
private String name;
/**
* 性别
*/
private String sex;
/**
* 年龄
*/
private int age;
/**
* 体重
*/
private float weight;
......
}
@Controller
public class TestController1 {
@RequestMapping( value = "/testbo")
public Object test(ModelAndView mov , HttpServletRequest request,
testBO bo) {
System.out.println(bo);
......
}
}
http://localhost:8080/testbo?name=a1&age=10
在 Controller的参数前面,增加 @Validated 注解:
import org.springframework.validation.annotation.Validated;
......
@RequestMapping( value = "/testbo")
public Object test(ModelAndView mov , HttpServletRequest request,
@Validated testBO bo) {
System.out.println(bo);
......
}
javax提供了一个 @Valid, 和 @Validated 有差别的;
在检验Controller的入参是否符合规范时,使用@Validated或者@Valid在基本验证功能上没有太多区别。但是在分组、注解地方、嵌套验证等功能上两个有所不同。
@Validated | @Valid | ||
注解地方 | 可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上 | 可以用在方法、构造函数、方法参数和成员属性(字段)上 | 两者是否能用于成员属性(字段)上直接影响能否提供嵌套验证的功能 |
分组 | 提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制,可参考高效使用hibernate-validator校验框架 | 作为标准JSR-303规范,不支持分组的功能 | |
JSR提供的校验注解:
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内@URL(protocol=,host=, port=, regexp=, flags=) 合法的url
主要区分下@NotNull @NotEmpty @NotBlank 3个注解的区别:
@NotNull 任何对象的value不能为null
@NotEmpty 集合对象的元素不为0,即集合不为空,也可以用于字符串不为null
@NotBlank 只能用于字符串不为null,并且字符串trim()以后length要大于0
先增加2个属性的校验:
public class testBO {
/**
* 姓名
*/
@NotNull
private String name;
/**
* 性别
*/
@Min(20)
private String sex;
获取校验结果:
@RequestMapping( value = "/testbo")
public Object test(ModelAndView mov , HttpServletRequest request,
@Validated testBO bo, BindingResult bindingResult) {
System.out.println( bindingResult.hasErrors());
if( bindingResult.hasErrors()) {
List errors = bindingResult.getAllErrors();
for( ObjectError err : errors) {
System.out.println(err.toString());
}
}
发起同样的请求:
http://localhost:8080/testbo?name=a1&age=10
查看Error:
有些时候,需要按照自己的业务规则进行校验,需要自定义校验规则;
@Documented
@Constraint(validatedBy = DayOfWeekValidator.class)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DayOfWeek {
String message() default "Unknown day of week";
Class[] groups() default {};
Class[] payload() default {};
}
public class DayOfWeekValidator implements ConstraintValidator {
private List daysOfWeek =
Arrays.asList("sunday", "monday", "tuesday",
"wednesday", "thursday", "friday", "saturday");
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) return true; // can be null
String input = value.trim().toLowerCase();
if (daysOfWeek.contains(input)) {
return true;
}
return false;
}
}