美文网首页
秒杀第十一节:优化校验规则

秒杀第十一节:优化校验规则

作者: 小石读史 | 来源:发表于2020-08-05 19:47 被阅读0次

    在之前用户用户注册时候,我们队参数的校验是这样写的

    if(StringUtils.isEmpty(userModel.getName())
            || userModel.getGender()==null
            || userModel.getAge() ==null
            || StringUtils.isEmpty(userModel.getTelphone())){
                throw new BussinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
            }
    

    这样的写法代码非常的臃肿,有没有更好的方法呢,答案是我们可以使用hibernate的Validator校验
    首先,我们需要在pom中引入validator

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

    在com.miaoshaprojec目录下新建valiator目录,然后新建类ValidationResult用于返回校验结果

    package com.miaoshaproject.valiator;
    
    import lombok.Getter;
    import lombok.Setter;
    import org.apache.commons.lang3.StringUtils;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @Auther: yql
     * @Date: 2019/4/4
     */
    public class ValidationResult {
        /**
         * 校验结果是否有错
         */
        @Setter
        private boolean hasErrors = false;
    
        /**
         * 存放错误信息的map
         */
        @Getter
        @Setter
        private Map<String, String> errorMsgMap = new HashMap<>();
    
        public boolean isHasErrors() {
            return hasErrors;
        }
    
        /**
         * 实现通用的通过格式化字符串信息获取错误结果的msg方法
         *
         * @return
         */
        public String getErrMsg() {
            return StringUtils.join(errorMsgMap.values().toArray(), ",");
        }
    }
    

    如果引用的StringUtils报错请在pom文件中引入下面的包

    <!-- apachee common lang -->
        <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-lang3</artifactId>
          <version>3.7</version>
        </dependency>
    

    新家ValidatorImpl implements InitializingBean 用于检验对象中传入的参数是否正确

    package com.miaoshaproject.valiator;
    
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.stereotype.Component;
    
    import javax.validation.ConstraintViolation;
    import javax.validation.Validation;
    import javax.validation.Validator;
    import java.util.Set;
    
    /**
     * @Auther: yql
     * @Date: 2019/4/4
     */
    @Component
    public class ValidatorImpl implements InitializingBean {
    
        private Validator validator;
    
        public ValidationResult validate(Object bean) {
            ValidationResult result = new ValidationResult();
            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 validator通过工厂的初始化方式使其实例化
            this.validator = Validation.buildDefaultValidatorFactory().getValidator();
        }
    }
    

    如果出现以下错误,直接打开 File --> Project Stucture 选择项目设置Lanugage level即可,


    image.png

    首先修改UserModel,增加校验规则
    修改前

    import lombok.Data;
    
    @Data
    public class UserModel {
        private Integer id;
        private String name;
        private Byte gender;
        private Integer age;
        private String telphone;
        private String registerMode;
        private String thirdPartyId;
        private String encrptPassword;
    }
    ~~~
    修改后
    ~~~
    import lombok.Data;
    
    import javax.validation.constraints.Max;
    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotBlank;
    import javax.validation.constraints.NotNull;
    
    @Data
    public class UserModel {
    
        private Integer 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;
    
        @NotBlank(message = "密码不能为空")
        private String encrptPassword;
    
    }
    ~~~
    修改UserServiceImpl中register方法中的校验,修改前
    ~~~
    @Transactional
        @Override
        public void register(UserModel userModel) throws BussinessException {
            if (userModel == null){
                throw new BussinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
            }
    
            if(StringUtils.isEmpty(userModel.getName())
            || userModel.getGender()==null
            || userModel.getAge() ==null
            || StringUtils.isEmpty(userModel.getTelphone())){
                throw new BussinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
            }
    
            //实现model->dataobject方法
            UserDO userDO = convertFromModel(userModel);
            //使用insertSelective而不是insert,insertSelective会将对象为null的字段不进行插入,使这个字段依赖数据库的默认值。
            try {
                userDOMapper.insertSelective(userDO);
            } catch (DuplicateKeyException e) {
                throw new BussinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,"手机号已被注册!");
            }
            userModel.setId(userDO.getId());
    
            UserPasswordDO userPasswordDO = convertPasswordFromModel(userModel);
            userPasswordDOMapper.insertSelective(userPasswordDO);
        }
    

    在UserServiceImpl引入

    @Autowired
        private ValidatorImpl validator;
    

    修改后

    @Transactional
        @Override
        public void register(UserModel userModel) throws BussinessException {
            if (userModel == null){
                throw new BussinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
            }
    
            /*if(StringUtils.isEmpty(userModel.getName())
            || userModel.getGender()==null
            || userModel.getAge() ==null
            || StringUtils.isEmpty(userModel.getTelphone())){
                throw new BussinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
            }*/
            ValidationResult result = validator.validate(userModel);
            System.out.println(result.getErrMsg()+"result");
            if (result.isHasErrors()) {
                throw new BussinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,result.getErrMsg());
            }
    
            //实现model->dataobject方法
            UserDO userDO = convertFromModel(userModel);
            //使用insertSelective而不是insert,insertSelective会将对象为null的字段不进行插入,使这个字段依赖数据库的默认值。
            try {
                userDOMapper.insertSelective(userDO);
            } catch (DuplicateKeyException e) {
                throw new BussinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,"手机号已被注册!");
            }
            userModel.setId(userDO.getId());
    
            UserPasswordDO userPasswordDO = convertPasswordFromModel(userModel);
            userPasswordDOMapper.insertSelective(userPasswordDO);
        }
    

    测试请求参数:http://localhost:8080/user/register?telphone=12345678913&otpCode=45106&name=li&gender=0&age=200&password=123456
    返回值:
    {
    "status": "fail",
    "data": {
    "errCode": 10001,
    "errMsg": "年龄不能大于150"
    }
    }

    相关文章

      网友评论

          本文标题:秒杀第十一节:优化校验规则

          本文链接:https://www.haomeiwen.com/subject/ptszkktx.html