Validatoin验证框架使用

2020-01-15  本文已影响0人  半日孤独

1.导入依赖

//springboot中导入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
//或者
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
    <version>5.2.4.Final</version>
 </dependency>

2.使用方法

model类
//普通方式使用
@Data
public class ItemModel {
    private  Integer id;

    /**
     * 商品名称
     */
    @NotBlank(message = "商品名称不能为空")
    private String title;

    /**
     * 商品价格
     */
    @NotNull(message = "商品价格不能为空")
    @Min(value = 0,message = "商品价格必须大于0")
    private BigDecimal price;

    /**
     * 商品的库存
     */
    @NotNull(message = "库存不能为空")
    private Integer stock;

    /**
     * 商品的描述
     */
    @NotBlank(message = "商品描述不能为空")
    private  String descript;

    /**
     * 商品的销量
     */
    private Integer sales;

    /**
     * 商品描述图片的url
     */
    @NotBlank(message = "商品图片不能为空")
    private String imgUrl;
}
//分组使用
@Data
public class User implements Serializable {
    /**
     * 登录场景
     */
    public interface LoginGroup {
    }
    /**
     * 注册场景
     */
    public interface RegisterGroup {
    }

    /**
     * 分组
     */
    @GroupSequence({
            LoginGroup.class,
            RegisterGroup.class,
            Default.class
    })
    public interface Group {
    }

    private Long id;
    @NotBlank(message = "用户名不能为空", groups = LoginGroup.class)
    private String username;
    @NotBlank(message = "密码不能为空")
    @Length(min = 6, max = 12, message = "密码应大于6位,小于12位")
    private String password;
    @NotBlank(message = "邮箱不能为空", groups = RegisterGroup.class)
    @Email(message = "请输入符合格式的邮箱")
    private String email;
    @Size(min = 1, message = "不能少于一个数据")
    private @Valid List<User> list;

}
controller类

1.使用方法一

//编写基础类
@RestControllerAdvice
public class BaseController {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultInfo<?> validationErrorHandler(MethodArgumentNotValidException ex) {
        // 同样是获取BindingResult对象,然后获取其中的错误信息
        // 如果前面开启了fail_fast,事实上这里只会有一个信息
        //如果没有,则可能又多个
        List<String> errorInformation = ex.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        return new ResultInfo<>(400, errorInformation.toString(), "");
    }
}
//通过抛出异常
@RestController
public class MyFirstController extends BaseController {
    @Autowired
    private Validator validator;
    /**
     * 接受值参数验证
     * @Validated(value = User.LoginGroup.class)
     * @Validated(value = User.RegisterGroup.class)
     *
     * @param user
     * @return
     */
    @RequestMapping(value = "test/validate", method = RequestMethod.POST)
    public User saveYhxx(@Validated(value = User.Group.class) @RequestBody User user ) throws NoSuchMethodException {
        //获取验证执行器
        ExecutableValidator ev =  validator.forExecutables();
        return user;
    }
}

2.使用方法二

//实现InitializingBean,InitializingBean bean对象初始化之后会调用
@Component
public class ValidatorImpl implements InitializingBean {
    private Validator validator;
    @Override
    public void afterPropertiesSet() throws Exception {
        //将hibernate validator通过工厂的初始化方式使其实例化
        this.validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    /**
     * 实现校验方法并返回校验结果
     * @param bean
     * @return
     */
    public VaildationResult validate(Object bean) {
        final VaildationResult result = new VaildationResult();
        Set<ConstraintViolation<Object>> constraintViolationSet =
                validator.validate(bean);
        if (constraintViolationSet.size() > 0) {
            //有错误
            result.setHasErrors(true);
            constraintViolationSet.forEach(value->{
                String errmsg = value.getMessage();
                String propertyName = value.getPropertyPath().toString();
                result.getErrMsgMap().put(propertyName,errmsg);
            });
        }
        return result;
    }
}

///同样抛出异常
    @Autowired
    private ValidatorImpl validator;
    @Override
    @Transactional
    public ItemModel createItem(ItemModel itemModel) throws BusinessExcception {
        //校验入参
        VaildationResult result =  validator.validate(itemModel);
        if(result.isHasErrors()){
            throw new BusinessExcception(EnBusinessErroe.PARAMETER_VALIDATION_ERROR,result.getErrMsg());
        }
        //转化itemModel->dataobject
        ItemDo itemDo = this.convertItemDOFromItemModel(itemModel);
        //写入数据库
        itemDoMapper.insertSelective(itemDo);
        itemModel.setId(itemDo.getId());
        ItemStockDo itemStockDo = this.convertItemStockDOFromItemModel(itemModel);
        itemStockDoMapper.insertSelective(itemStockDo);

        //返回创建完成的对象
        return this.getItemById(itemModel.getId());
    }

2.使用方法二

public class CommonUtils {
    /**
     * 获取校验框架返回的错误信息进行封装
     * @param errResult
     * @return
     */
    public static String getValidation(BindingResult errResult) {
        StringBuilder msg=new StringBuilder();
        if(errResult.hasFieldErrors()){
            for (ObjectError error : errResult.getAllErrors()) {
                msg.append(error.getDefaultMessage());
                msg.append("!");
            }
        }
        return msg.toString();
        
    }
//调用
 public DataResult (@RequestBody @Validated User bean, BindingResult errResult) {
        DataResult result = new DataResult();
        if (errResult.hasErrors()) {
            result.setSuccess(false);
            result.setMsg(CommonUtils.getValidation(errResult));
            return result;
        }

3.总结

可以减少很多的验证校验,简化很多的代码,做到优雅,好维护。

上一篇下一篇

猜你喜欢

热点阅读