zoukankan      html  css  js  c++  java
  • springmvc使用JSR-303对复杂对象进行校验

    JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,官方参考实现是Hibernate Validator。此实现与Hibernate ORM 没有任何关系。JSR 303 用于对Java Bean 中的字段的值进行验证。

    1.配置Maven

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
        </dependency>
    

    2.编写需要校验的bean

    public class QuestionnaireDetailDto {
    
        /**问卷id*/
        private BigInteger key;
    
        /**问卷标题*/
        @NotBlank(message = "请输入问卷标题")
        private String title;
    
        /**问卷备注*/
        @NotBlank(message = "请输入问卷备注")
        private String note;
    
        /**问卷对应的策略*/
        private List<BigInteger> strategys = Lists.newArrayList();
    
        /**题目list*/
        @Size(min = 1, max = 10, message = "可输入1-10个题目")
        private List<QuestionDto> questions = Lists.newArrayList();
        //省略get,set,toString方法
     }

    3.校验

    @ResponseBody
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public Object addQuestionnaire(@Validated @RequestBody QuestionnaireDetailDto questionnaireDetailDto, BindingResult bindingResult) {
        validQuestionnaireDetailDto(bindingResult);
        if (questionnaireService.addQuestionnaire(questionnaireDetailDto)) {
            LOGGER.info("添加问卷成功");
            return JsonResult.getSuccessMessage("添加问卷成功");
        } else {
            LOGGER.error("添加问卷失败");
            return JsonResult.getErrorMessage("添加问卷失败");
        }
    }
    

    valid方法和validQuestionnaireDetailDto方法:

    @Autowired
    protected Validator validator;
    
    protected void validData(BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            StringBuffer sb = new StringBuffer();
            for (ObjectError error : bindingResult.getAllErrors()) {
                sb.append(error.getDefaultMessage());
            }
            throw new DataException(sb.toString());
        }
    }
    
    /**
     * 对QuestionnaireDetailDto参数校验
     *
     * @param bindingResult bindingResult
     */
    protected void validQuestionnaireDetailDto(BindingResult bindingResult) {
        validData(bindingResult);
    
        //如果bindingResult中有List<pojo>,只通过bindingResult.hasErrors是检测不到pojo中的异常的
        //针对这种情况,先取到List<pojo>对象,再进行验证
        Object object = bindingResult.getModel().get(bindingResult.getObjectName());
    
        QuestionnaireDetailDto questionnaireDetailDto = (QuestionnaireDetailDto) object;
        List<QuestionDto> questionDtos = questionnaireDetailDto.getQuestions();
    
        for (QuestionDto questionDto : questionDtos) {
            validateWithException(validator, questionDto);
            //拿到questionDto中的options属性(类型为List<ChoiceDto>)
            List<ChoiceDto> choiceDtos = questionDto.getOptions();
            for (ChoiceDto choiceDto : choiceDtos) {
                validateWithException(validator, choiceDto);
            }
        }
    }
    
    /**
     * 服务端参数有效性验证
     *
     * @param object 验证的实体对象
     * @param groups 验证组
     * @return 验证成功:返回true;验证失败:将错误信息添加到message中
     */
    @SuppressWarnings("rawtypes")
    protected static void validateWithException(Validator validator, Object object, Class<?>... groups) {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty()) {
            StringBuffer sb = new StringBuffer();
            for (ConstraintViolation constraintViolation : constraintViolations) {
                sb.append(constraintViolation.getMessage());
            }
            throw new DataException(sb.toString());
        }
    }

    需要注意的是:如果仅仅调用validData方法,校验不到QuestionnaireDetailDto中QuestionDto的属性,所以重写了一个validQuestionnaireDetailDto。

    此时需要多引入两个依赖:

                <dependency>
                    <groupId>javax.el</groupId>
                    <artifactId>el-api</artifactId>
                    <version>2.2</version>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>el-impl</groupId>
                    <artifactId>el-impl</artifactId>
                    <version>1.0</version>
                </dependency>    
    

      

  • 相关阅读:
    Edge浏览器主页被360劫持怎么办 ?
    wpf小技巧——datagrid 不出现 滚动条问题
    c++学习资料
    Mosquitto创建MQTT服务器提示Starting in local only mode的解决办法
    【转】在 Golang 中使用 Cobra 创建 CLI 应用
    【转】Golang的HTTP操作大全
    BigDecimal类中的3个toString方法
    Path is not a working copy directory
    Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
    sqlserver判断字符串是否是纯数字
  • 原文地址:https://www.cnblogs.com/jlustone/p/7515904.html
Copyright © 2011-2022 走看看