当前位置: 首页 > 科技观察

SpringBoot接口参数统一校验

时间:2023-03-22 17:06:50 科技观察

SpringBoot检查注解@Null只能为null。@NotNull限制不能为空。@NotEmpty只对字符串类型有效,字符串不为空,长度不为0。@NotBlank只对字符串类型有效,字符串不为空,trim()不为空字符串。@AssertFalse约束必须为假。@AssertTrue约束必须为真。@DecimalMax(value)限制必须是一个不大于指定值的数字。@DecimalMin(value)限制必须是一个不小于指定值的数字。@Digits(integer,fraction)限制必须是小数,整数部分的位数不能超过整数,小数部分的位数不能超过分数。@Future约束必须是未来的日期。@Past验证注解的元素值(日期类型)早于当前时间。@Max(value)限制必须是一个不大于指定值的数字。@Min(value)限制必须是一个不小于指定值的数字。@Pattern(value)约束必须匹配指定的正则表达式。@Size(max,min)限制字符长度必须在min和max之间。@Email验证注解的元素值为Email,也可以通过正则表达式和flags指定自定义的邮件格式。注意:@NotNull适用于任何类型的不能为NULL的注释元素。@NotEmpty适用于StringMap或数组不能为Null且长度必须大于0。@NotBlank只能用在String上,不能为null。调用trim()后长度必须大于0单参数验证@RestController@RequestMapping("validator/")@ValidatedpublicclassValidatorController{@GetMapping("/add")publicStringadd(@NotNull(message="地址不能为空")Stringaddress){return"validatorPass";}}请求:127.0.0.1:8080/validator/add?address=中国。返回:通过测试。请求:127.0.0.1:8080/验证器/添加。返回:地址不能为空。注意:在进行单参数校验时,必须在Controler类中添加@Validated注解,否则校验不生效。实体类参数校验EntityUser类:publicclassUser{@NotBlank(message="请输入姓名")@Length(message="姓名不能超过{max}个字符",max=5)publicStringname;@NotNull(message="请输入您的年龄")@Range(message="年龄介于{min}和{max}之间",min=1,max=100)publicIntegerage;publicStringgetName(){返回名称;}publicvoidsetName(Stringname){this.name=name;}publicIntegergetAge(){returnage;}publicvoidsetAge(Integerage){this.age=age;}}控制器类:@RestController@RequestMapping("validator/")publicclassValidatorController{@PostMapping("/add")publicStringaddUser(@RequestBody@ValidUseruser,BindingResultbindingResult){//检查所有字段是否被验证if(bindingResult.hasErrors()){//返回第一条错误信息returnbindingResult.getAllErrors().get(0).getDefaultMessage();}返回“测试通过”;}}执行如下:注意:如果使用BindingResult存储异常结果,必须自己处理异常。即如果接口中有BindingResult参数,则必须使用上述7、8、9行代码进行异常处理,否则程序会正常执行。统一的异常管理实体User类,同上。控制器类如下:@RequestMapping("validator/")publicclassValidatorController{@PostMapping("/add")publicStringaddUser(@Valid@RequestBodyUseruser){return"validationpassed";}}执行结果:这里没有使用BindingResult来存储异常,程序会在这里报错。这个地方可以加入统一的异常管理。通过通过报错信息信息可以需要需要方法argumentNotValidexception进行,代码:@restControllerAdvicePublicclassclassclassviralatedexectionhander{@expectionhander{@expectionhander{methodarggumentnotvalidexection.class)).getDefaultMessage();返回异常信息;}}再次执行:使用springbootvalidatorValidator代码:@ComponentpublicclassValidatorUtilimplementsApplicationContextAware{//通过Spring获取validatorprivatestaticValidatorvalidator;@OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext){ValidatorvalidatorBean=applicationContext.getBean(Validator.class);setValidator(validatorBean);}publicstaticvoidsetValidator(ValidatorvalidatorBean){if(validatorBeaninstanceofLocalValidatorFactoryBean){validator=((LocalValidatorFactoryBean)ean).getValidator();}elseif(validatorBeaninstanceofSpringValidatorAdapter){validator=validatorBean.unwrap(Validator.class);}else{validator=validatorBean;}}publicstaticvoidvalidate(Tobject){Set>violationSet=validator.validate(object);for(ConstraintViolationviolation:violationSet){抛出新的ValidationException(violation.getMessage());}}}统一异常管理:@RestControllerAdvicepublicclassValidatedExceptionHander{@ExceptionHandler(value=ValidationException.class)publicStringValidationException(ValidationExceptionexception){returnexception.getMessage();}}controller类如下:@RestController@RequestMapping("validator/")publicclassValidatorController{@PostMapping("/add")publicStringaddUser(@RequestBodyUseruser){ValidatorUtil.validate(user);return"验证通过";}}执行如下:说明:这样做的好处是可以自由检查实体。与上述方法相比,分组验证更加灵活。同一个实体在不同的操作中有不同的验证方式。是的,这需要组验证。例如,当实体User新增操作时,id不存在,但进行update操作时,id必须存在。用下面的例子来说明如何实现。实体用户:publicclassUser{@NotNull(message="id不能为空",groups={User.UpdateGroup.class})@Null(message="id必须为空",groups={User.InsertGroup.class})公共整数标识;@NotBlank(message="请输入姓名")@Length(message="姓名不能超过{max}个字符",max=5)publicStringname;@NotNull(message="请输入年龄")@Range(message="年龄介于{min}和{max}之间",min=1,max=100)publicIntegerage;publicIntegergetId(){returnid;}publicvoidsetId(Integerid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicIntegergetAge(){returnage;}publicvoidsetAge(Integerage){this.age=age;}publicinterfaceInsertGroup{}publicinterfaceUpdateGroup{}}统一异常:@RestControllerAdvicepublicclassValidatedExceptionHander{@ExceptionHandler(MethodArgumentNotValidException.类)publicStringMethodArgumentNotValidHandler(MethodArgumentNotValidExceptionexception){StringexceptionInfo=exception.getBindingResult().getAllErrors().get(0).getDefaultMessage();返回异常信息;}}控制器类:@RestController@RequestMapping("validator/")publicclassValidatorController{@GetMapping("/update")publicStringupdateUser(@Validated(User.UpdateGroup.class)@RequestBodyUseruser){return"更新成功";}@GetMapping("/insert")publicStringinsertUser(@Validated(User.InsertGroup.class)@RequestBodyUseruser){return"保存成功";}}执行如下:@Validated和@Valid不同@Validated对@Valid进行了两次封装,但是它有分组、注解位置、嵌套校验等功能,区别@Valid@Validated源码是Hibernate的校验注解validation是SpringValidator的验证注解,它是在Hibernate验证的基础上增加的版本。注解的位置用在构造函数、方法、方法参数和类中的成员属性、方法和方法参数中。但是,它不能用于成员属性的嵌套验证。它用于级联对象的成员属性。没有这个功能不支持分组。可以提供分组功能,进入参数校验时可以根据不同的分组使用不同的校验机制。