Example usage for org.springframework.web.bind WebDataBinder getBindingErrorProcessor

List of usage examples for org.springframework.web.bind WebDataBinder getBindingErrorProcessor

Introduction

In this page you can find the example usage for org.springframework.web.bind WebDataBinder getBindingErrorProcessor.

Prototype

public BindingErrorProcessor getBindingErrorProcessor() 

Source Link

Document

Return the strategy for processing binding errors.

Usage

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

/**
 * Construct a new attribute instance with the given constructor.
 * <p>Called from/*from   w  w  w  .j av a  2s.  co m*/
 * {@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);
}