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

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

作者: 小石读史 | 来源:发表于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"
}
}

相关文章

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

    在之前用户用户注册时候,我们队参数的校验是这样写的 这样的写法代码非常的臃肿,有没有更好的方法呢,答案是我们可以使...

  • 电商高并发秒杀5 流量削峰技术

    前言 对应的交易优化技术使用了缓存校验+异步扣减库存的方式,使得秒杀下单的方式有了明显的提升。即便查询优化,交易优...

  • 设计模式之责任链模式

    抽象处理者 校验的具体规则类 校验用户昵称 校验邮箱 校验状态 校验密码 校验规则客户端 输出结果

  • Kettle 实战之 (3) 数据校验

    实例 增加节点-数据校验 1、从【校验】节点分类中选择【数据校验】 2、设置校验规则点击【增加校验】,增加校验规则...

  • Element-UI表单验证

    校验规则 表单通过rules属性绑定校验规则对象,表单项通过prop属性绑定具体校验规则 注意校验的字段必须和表单...

  • element-ui 的行自定义校验。

    写的校验方法要放在计算属性里 自定义校验规则 rules 校验规则

  • RabbitMQ如何在秒杀项目中翻江倒海

    摘要:本篇博文是“Java秒杀系统实战系列文章”的第十七篇,我们将继续秒杀系统的优化之路。在本篇文章中我们将基于R...

  • vue中关于密码复杂度的校验

    以下代码是根据自己的项目里面关于密码复杂度的一个校验,也比较符合目前比较主流的校验规则,并且进行了相应的优化; i...

  • 在后端Controller层校验前台传来的数据

    一、引入依赖 二、javaBean上设置校验规则 三、Controller层返回校验错误信息 将不符合校验规则的字...

  • 校验规则

    1.验证手机号 /^1[3|5|6|7|8]\d{9}$/ 2.验证密码(6-16位字母/数字/下划线------...

网友评论

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

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