秒殺第十一節:優化校驗規則

在之前用戶用戶註冊時候,我們隊參數的校驗是這樣寫的

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即可,


首先修改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"
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章