温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么使用Bean Validation解决业务中参数校验

发布时间:2021-07-28 13:43:05 来源:亿速云 阅读:186 作者:小新 栏目:开发技术

这篇文章将为大家详细讲解有关怎么使用Bean Validation解决业务中参数校验,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

叙述

Bean Validation是一个通过配置注解来验证参数的框架,它包含两部分Bean Validation API和Hibernate Validator。

Bean Validation API是Java定义的一个验证参数的规范。

Hibernate Validator是Bean Validation API的一个实现。

@Valid和Validated的比较

Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR-303规范),配合BindingResult可以直接提供参数验证结果。

@Valid : 没有分组功能,可以用在方法、构造函数、方法参数和成员属性(field)上,如果一个待验证的pojo类,其中还包含了待验证的对象,需要在待验证对象上注解@valid,才能验证待验证对象中的成员属性

@Validated :提供分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制,用在类型、方法和方法参数上。但不能用于成员属性(field)。

两者都可以用在方法入参上,但都无法单独提供嵌套验证功能,都能配合嵌套验证注解@Valid进行嵌套验证。

嵌套验证示例:

public class ClassRoom{     @NotNull     String name;          @Valid  // 嵌套校验,校验参数内部的属性     @NotNull     Student student; }
  @GetMapping("/room")   // 此处可使用 @Valid 或 @Validated, 将会进行嵌套校验     public String validator(@Validated ClassRoom classRoom, BindingResult result) {         if (result.hasErrors()) {             return result.getFieldError().getDefaultMessage();         }         return "ok";     }
BindingResult 的使用

BindingResult必须跟在被校验参数之后,若被校验参数之后没有BindingResult对象,将会抛出BindException。

@GetMapping("/room")     public String validator(@Validated ClassRoom classRoom, BindingResult result) {         if (result.hasErrors()) {             return result.getFieldError().getDefaultMessage();         }         return "ok";     }

不要使用 BindingResult 接收String等简单对象的错误信息。简单对象校验失败,会抛出 ConstraintViolationException。主要就是接不着,你要写也算是没关系…

  // ❌ 错误用法,也没有特别的错,只是 result 是接不到值。     @GetMapping("/room")     @Validated  // 启用校验     public String validator(@NotNull String name, BindingResult result) {         if (result.hasErrors()) {             return result.getFieldError().getDefaultMessage();         }         return "ok";     }

修改校验失败的提示信息

可以通过各个校验注解的message属性设置更友好的提示信息。

public class ClassRoom{     @NotNull(message = "Classroom name must not be null")     String name;          @Valid     @NotNull     Student student; }
 @GetMapping("/room")     @Validated     public String validator(ClassRoom classRoom, BindingResult result, @NotNull(message = "姓名不能为空") String name) {         if (result.hasErrors()) {             return result.getFieldError().getDefaultMessage();         }         return "ok";     }

message属性配置国际化的消息也可以的,message中填写国际化消息的code,在抛出异常时根据code处理一下就好了。

@GetMapping("/room")     @Validated     public String validator(@NotNull(message = "demo.message.notnull") String name) {         if (result.hasErrors()) {             return result.getFieldError().getDefaultMessage();         }         return "ok";     }
// message_zh_CN.properties demo.message.notnull=xxx消息不能为空 // message_en_US.properties demo.message.notnull=xxx message must no be null

hibernate-validator 的使用

1.引入pom

<dependency>     <groupId>org.hibernate</groupId>     <artifactId>hibernate-validator</artifactId>     <version>5.3.1.Final</version> </dependency>

2.dto入参对象属性加入注解

@Data public class UserModel implements Serializable {     private String id;     @NotBlank(message = "用户名不能为空")     private String name;     @NotNull(message = "性别不能不填")     private Byte gender;     @NotNull(message = "年龄不能不填")     @Min(value = 0,message = "年龄必须大于0岁")     @Max(value = 150,message = "年龄必须小于150岁")     private Integer age;          @NotBlank(message = "手机号不能不填")     private String telphone;          private String registerMode;     private String thirdPartyId;     private String encrptPassward; }

方法一:3.controller方法入参加入校验(@Validated )

@GetMapping("/getUser")     public String validator(@Validated UserModel userModel , BindingResult result) {         if (result.hasErrors()) {             return result.getFieldError().getDefaultMessage();         }         return "ok";     }

方法二:3.自定义封装ValidatorImpl类

@Component public class ValidatorImpl implements InitializingBean{     private Validator validator;     //实现校验方法并返回校验结果     public ValidationResult validate(Object bean){         final   ValidationResult result=new ValidationResult();         Set<ConstraintViolation<Object>> validate = validator.validate(bean);         if (validate.size()>0) {             result.setHasError(true);             validate.forEach(constraintViolation->{                 String errMsg=constraintViolation.getMessage();                 String propertyName=constraintViolation.getPropertyPath().toString();                 result.getErrorMsgMap().put(propertyName,errMsg);             });         }         return result;     }     @Override     public void afterPropertiesSet() throws Exception {         this.validator= Validation.buildDefaultValidatorFactory().getValidator();     } }

方法二:4.自定义封装ValidationResult 类

public class ValidationResult {     public boolean hasError=false;     private Map<String,String> errorMsgMap=new HashMap<>();     //实现通用的通过格式化字符串信息获取错误结果的msg方法     public String getErrMsg(){         return StringUtils.join(errorMsgMap.values().toArray(),",");     }     public boolean isHasError() {         return hasError;     }     public void setHasError(boolean hasError) {         this.hasError = hasError;     }     public Map<String, String> getErrorMsgMap() {         return errorMsgMap;     }     public void setErrorMsgMap(Map<String, String> errorMsgMap) {         this.errorMsgMap = errorMsgMap;     } }

5.controller方法入参加入校验

   @Autowired    private ValidatorImpl validator;     @Override        @Transactional(rollbackFor = Exception.class)     public void register(UserModel userModel) throws BusinessException {         UserDo userDo=new UserDo();         if (userModel == null) {             throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);         }   //validate进行入参校验        ValidationResult validate = validator.validate(userModel);         if (validate.isHasError()){             throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,validate.getErrMsg());         }     }

Bean Validation 的约束

  • @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(value) 被注释的元素必须符合指定的正则表达式

Hibernate Validator 附加的约束

Hibernate Validator 附加的 constraint:

  • @Email 被注释的元素必须是电子邮箱地址

  • @Length 被注释的字符串的大小必须在指定的范围内

  • @NotEmpty 被注释的字符串的必须非空

  • @Range 被注释的元素必须在合适的范围内

关于“怎么使用Bean Validation解决业务中参数校验”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI