👳我亲爱的各位大佬们好
♨️本篇文章记录的为 Hibernate Validator Engine相关内容,适合在学Java的小白,帮助新手快速上手,也适合复习中,面试中的大佬🙉🙉🙉。
♨️如果文章有什么需要改进的地方还请大佬不吝赐教❤️🧡💛
👨🔧 个人主页 : 阿千弟
@[toc]
场景:
我们在注册用户的时候必定会对前端传过来的用户信息进行参数校验, 就像下面这段代码
public void register(UserModel userModel) throws BusinessException {
if(userModel == null){
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
}
if(StringUtils.isEmpty(userModel.getName())
|| userModel.getGender() == null
|| userModel.getAge() == null
|| StringUtils.isEmpty(userModel.getTelephone())){
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
}
问题:
我们发现了很严重的问题, 上面的这段代码对属性的判断不仅单一, 而且想要进行更为复杂的校验时代码的编写成本不仅过高, 而且不利于后期的维护, 如果用户实体类中加入了新的属性, 这里的代码还需重构,可维护行极差.
解决方案
这时候就需要一个功能更为强大的属性校验器
Hibernate Validator Engine: 没错,正是在下
validator Engine 是支持Javax.validator 的接口的实现, 并且可以通过一些简单的标注的形式(annotation形式)实现一个校验的形式, 它其实也是一个约定大于执行的过程
目前它的最新的版本是 Sep 09, 2022 的 8.0.0.Final版
优化后
导入maven依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
ValidationResult
编写错误时时返回结果
public class ValidationResult {
//校验结果是否有错
private boolean hasErrors;
//存放错误信息的map
private Map<String,String> errorMsgMap;
public ValidationResult() {
hasErrors = false;
errorMsgMap = new HashMap<>();
}
public boolean isHasErrors() {
return hasErrors;
}
public void setHasErrors(boolean hasErrors) {
this.hasErrors = hasErrors;
}
public Map<String, String> getErrorMsgMap() {
return errorMsgMap;
}
public void setErrorMsgMap(Map<String, String> errorMsgMap) {
this.errorMsgMap = errorMsgMap;
}
//实际通用的通过格式化字符串信息获取错误结果的msg方法
public String getErrMsg(){
return StringUtils.join(errorMsgMap.values().toArray(),",");
}
}
ValidatorImpl
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;
@Component
public class ValidatorImpl implements InitializingBean {
private Validator validator;
//实现校验方法并返回校验结果
public ValidationResult validate(Object bean){
ValidationResult result = new ValidationResult();
//如果bean里面的参数的规则有违背对应validation对应的annotation的话,就会被放入set中
Set<ConstraintViolation<Object>> constraintViolationSet = validator.validate(bean);
if(constraintViolationSet.size() > 0){
//有错误
result.setHasErrors(true);
constraintViolationSet.forEach(constraintViolation->{
/**
* 获取每个字段的错误信息
*/
String errMsg = constraintViolation.getMessage();
String propertyName = constraintViolation.getPropertyPath().toString();
result.getErrorMsgMap().put(propertyName, errMsg);
});
}
return result;
}
@Override
public void afterPropertiesSet() throws Exception {
//将 hibernate validation通过工厂的初始化方式使其实例化
this.validator = Validation.buildDefaultValidatorFactory().getValidator();
}
}
使用这样一种简单的方式我们以后只需要在Modle类要校验的属性上加上注解就可以了
@Data
@NoArgsConstructor
public class UserModel implements Serializable {
private Integer id;
@NotBlank(message = "用户名不能为空")
private String name;
@NotNull(message = "性别不能为空")
private Byte gender;
@NotNull(message = "年龄不能为空")
@Min(value = 0,message = "年龄不能为负哦")
@Max(value = 150,message = "年龄必须小于150岁")
private Integer age;
@NotBlank(message = "用手机号不能为空")
private String telephone;
private String registerMode;
private String thirdPartyId;
@NotBlank(message = "密码不能为空")
private String encrptPassword;
}
重新编写注册用户中的属性判断方法
public void register(UserModel userModel) throws BusinessException {
if(userModel == null){
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
}
ValidationResult result = validator.validate(userModel);
if(result.isHasErrors()){
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, result.getErrMsg());
}
测试: 故意把年龄填大一些
发生错误时,对应的注解上的message就显示出来了
问题完美解决
总结:
这样做的好处, 操作很简单, 如果后期有新增的属性字段, 直接在Model实体类添加相关的字段和注解就ok了, 不需要在service中更变原来已有的代码, 最重要的是用户在填写信息发生错误时, 错误信息可以及时反馈给前端, 给予用户更好的体验感
如果这篇【文章】有帮助到你💖,希望可以给我点个赞👍,创作不易,如果有对Java后端或者对
spring
感兴趣的朋友,请多多关注💖💖💖
👨🔧 个人主页 : 阿千弟