Example usage for org.springframework.validation AbstractBindingResult recordFieldValue

List of usage examples for org.springframework.validation AbstractBindingResult recordFieldValue

Introduction

In this page you can find the example usage for org.springframework.validation AbstractBindingResult recordFieldValue.

Prototype

@Override
    public void recordFieldValue(String field, Class<?> type, @Nullable Object value) 

Source Link

Usage

From source file:org.springframework.web.method.annotation.ModelAttributeMethodProcessor.java

/**
 * Construct a new attribute instance with the given constructor.
 * <p>Called from/*w  ww.  j  av a2  s . c  om*/
 * {@link #createAttribute(String, MethodParameter, WebDataBinderFactory, NativeWebRequest)}
 * after constructor resolution.
 * @param ctor the constructor to use
 * @param attributeName the name of the attribute (never {@code null})
 * @param binderFactory for creating WebDataBinder instance
 * @param webRequest the current request
 * @return the created model attribute (never {@code null})
 * @throws BindException in case of constructor argument binding failure
 * @throws Exception in case of constructor invocation failure
 * @since 5.0
 */
protected Object constructAttribute(Constructor<?> ctor, String attributeName,
        WebDataBinderFactory binderFactory, NativeWebRequest webRequest) throws Exception {

    if (ctor.getParameterCount() == 0) {
        // A single default constructor -> clearly a standard JavaBeans arrangement.
        return BeanUtils.instantiateClass(ctor);
    }

    // A single data class constructor -> resolve constructor arguments from request parameters.
    ConstructorProperties cp = ctor.getAnnotation(ConstructorProperties.class);
    String[] paramNames = (cp != null ? cp.value() : parameterNameDiscoverer.getParameterNames(ctor));
    Assert.state(paramNames != null, () -> "Cannot resolve parameter names for constructor " + ctor);
    Class<?>[] paramTypes = ctor.getParameterTypes();
    Assert.state(paramNames.length == paramTypes.length,
            () -> "Invalid number of parameter names: " + paramNames.length + " for constructor " + ctor);

    Object[] args = new Object[paramTypes.length];
    WebDataBinder binder = binderFactory.createBinder(webRequest, null, attributeName);
    String fieldDefaultPrefix = binder.getFieldDefaultPrefix();
    String fieldMarkerPrefix = binder.getFieldMarkerPrefix();
    boolean bindingFailure = false;

    for (int i = 0; i < paramNames.length; i++) {
        String paramName = paramNames[i];
        Class<?> paramType = paramTypes[i];
        Object value = webRequest.getParameterValues(paramName);
        if (value == null) {
            if (fieldDefaultPrefix != null) {
                value = webRequest.getParameter(fieldDefaultPrefix + paramName);
            }
            if (value == null && fieldMarkerPrefix != null) {
                if (webRequest.getParameter(fieldMarkerPrefix + paramName) != null) {
                    value = binder.getEmptyValue(paramType);
                }
            }
        }
        try {
            MethodParameter methodParam = new MethodParameter(ctor, i);
            if (value == null && methodParam.isOptional()) {
                args[i] = (methodParam.getParameterType() == Optional.class ? Optional.empty() : null);
            } else {
                args[i] = binder.convertIfNecessary(value, paramType, methodParam);
            }
        } catch (TypeMismatchException ex) {
            ex.initPropertyName(paramName);
            binder.getBindingErrorProcessor().processPropertyAccessException(ex, binder.getBindingResult());
            bindingFailure = true;
            args[i] = value;
        }
    }

    if (bindingFailure) {
        if (binder.getBindingResult() instanceof AbstractBindingResult) {
            AbstractBindingResult result = (AbstractBindingResult) binder.getBindingResult();
            for (int i = 0; i < paramNames.length; i++) {
                result.recordFieldValue(paramNames[i], paramTypes[i], args[i]);
            }
        }
        throw new BindException(binder.getBindingResult());
    }

    return BeanUtils.instantiateClass(ctor, args);
}