秒杀第十一节:优化校验规则
2020-08-05 本文已影响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"
}
}