• springmvc validator和springContext validator的区别


    1.springContext validator 依赖于代理实现

    MethodValidationInterceptor

            Set<ConstraintViolation<Object>> result;
    
            try {
                result = execVal.validateParameters(
                        invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
            }
            catch (IllegalArgumentException ex) {
                // Probably a generic type mismatch between interface and impl as reported in SPR-12237 / HV-1011
                // Let's try to find the bridged method on the implementation class...
                methodToValidate = BridgeMethodResolver.findBridgedMethod(
                        ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass()));
                result = execVal.validateParameters(
                        invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
            }
            if (!result.isEmpty()) {
                throw new ConstraintViolationException(result);
            }
    
            Object returnValue = invocation.proceed();

    2.springmvc validator 在 RequestResponseBodyMethodProcessor 中处理

    @Override
        public void validate(Object target, Errors errors, Object... validationHints) {
            if (this.targetValidator != null) {
                processConstraintViolations(
                        this.targetValidator.validate(target, asValidationGroups(validationHints)), errors);
            }
        }

    主要区别:mvc会帮我们对返回的Set<ConstraintViolation<Object>> violations 进行封装,易于返回

        protected void processConstraintViolations(Set<ConstraintViolation<Object>> violations, Errors errors) {
            for (ConstraintViolation<Object> violation : violations) {
                String field = determineField(violation);
                FieldError fieldError = errors.getFieldError(field);
                if (fieldError == null || !fieldError.isBindingFailure()) {
                    try {
                        ConstraintDescriptor<?> cd = violation.getConstraintDescriptor();
                        String errorCode = determineErrorCode(cd);
                        Object[] errorArgs = getArgumentsForConstraint(errors.getObjectName(), field, cd);
                        if (errors instanceof BindingResult) {
                            // Can do custom FieldError registration with invalid value from ConstraintViolation,
                            // as necessary for Hibernate Validator compatibility (non-indexed set path in field)
                            BindingResult bindingResult = (BindingResult) errors;
                            String nestedField = bindingResult.getNestedPath() + field;
                            if (nestedField.isEmpty()) {
                                String[] errorCodes = bindingResult.resolveMessageCodes(errorCode);
                                ObjectError error = new ObjectError(
                                        errors.getObjectName(), errorCodes, errorArgs, violation.getMessage());
                                error.wrap(violation);
                                bindingResult.addError(error);
                            }
                            else {
                                Object rejectedValue = getRejectedValue(field, violation, bindingResult);
                                String[] errorCodes = bindingResult.resolveMessageCodes(errorCode, field);
                                FieldError error = new FieldError(errors.getObjectName(), nestedField,
                                        rejectedValue, false, errorCodes, errorArgs, violation.getMessage());
                                error.wrap(violation);
                                bindingResult.addError(error);
                            }
                        }
                        else {
                            // got no BindingResult - can only do standard rejectValue call
                            // with automatic extraction of the current field value
                            errors.rejectValue(field, errorCode, errorArgs, violation.getMessage());
                        }
                    }
                    catch (NotReadablePropertyException ex) {
                        throw new IllegalStateException("JSR-303 validated property '" + field +
                                "' does not have a corresponding accessor for Spring data binding - " +
                                "check your DataBinder's configuration (bean property versus direct field access)", ex);
                    }
                }
            }
        }
    if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
                        throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
                    }
  • 相关阅读:
    Golang项目之函数版学生管理系统
    Golang项目之结构体版学生管理系统
    Golang基础之结构体
    前端开发必备组件库【基于原生js、兼容主流浏览器、B/S必备】
    兼容主流浏览器的js原生函数封装
    基于原生js的返回顶部组件,兼容主流浏览器
    javascript数组详解(js数组深度解析)【forEach(),every(),map(),filter(),reduce()】
    javascript中的字符串编码、字符串方法详解
    面试题中常见的类型转换陷阱
    node.js报错throw err; // Rethrow non-MySQL errors e:serverTest ode_modulesmysqllibprotocolParser.js:79 解决方法
  • 原文地址:https://www.cnblogs.com/z-test/p/11578115.html
Copyright © 2020-2023  润新知