diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java index af72c3bf65fd..e3e8c15e882e 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java @@ -112,7 +112,7 @@ public Mono resolveArgument( ResolvableType valueType = (adapter != null ? type.getGeneric() : type); Assert.state(adapter == null || !adapter.isMultiValue(), - () -> getClass().getSimpleName() + " doesn't support multi-value reactive type wrapper: " + + () -> getClass().getSimpleName() + " does not support multi-value reactive type wrapper: " + parameter.getGenericParameterType()); String name = getAttributeName(parameter); @@ -169,7 +169,7 @@ private Mono prepareAttributeMono(String attributeName, ResolvableType attrib if (attribute == null) { Class attributeClass = attributeType.getRawClass(); Assert.state(attributeClass != null, "No attribute class"); - return createAttribute(attributeName,attributeClass , context, exchange); + return createAttribute(attributeName, attributeClass, context, exchange); } ReactiveAdapter adapterFrom = getAdapterRegistry().getAdapter(null, attribute); @@ -230,9 +230,23 @@ private Mono createAttribute( () -> "Invalid number of parameter names: " + paramNames.length + " for constructor " + ctor); Object[] args = new Object[paramTypes.length]; WebDataBinder binder = context.createDataBinder(exchange, null, attributeName); + String fieldDefaultPrefix = binder.getFieldDefaultPrefix(); + String fieldMarkerPrefix = binder.getFieldMarkerPrefix(); for (int i = 0; i < paramNames.length; i++) { - Object value = bindValues.get(paramNames[i]); - value = (value != null && value instanceof List ? ((List) value).toArray() : value); + String paramName = paramNames[i]; + Class paramType = paramTypes[i]; + Object value = bindValues.get(paramName); + if (value == null) { + if (fieldDefaultPrefix != null) { + value = bindValues.get(fieldDefaultPrefix + paramName); + } + if (value == null && fieldMarkerPrefix != null) { + if (bindValues.get(fieldMarkerPrefix + paramName) != null) { + value = binder.getEmptyValue(paramType); + } + } + } + value = (value instanceof List ? ((List) value).toArray() : value); args[i] = binder.convertIfNecessary(value, paramTypes[i], new MethodParameter(ctor, i)); } return BeanUtils.instantiateClass(ctor, args); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java index 381f13a16d29..73ce43eb254f 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java @@ -301,6 +301,8 @@ private void testBindBar(MethodParameter param) throws Exception { assertTrue(map.get(bindingResultKey) instanceof BindingResult); } + // TODO: SPR-15871, SPR-15542 + private ModelAttributeMethodArgumentResolver createResolver() { return new ModelAttributeMethodArgumentResolver(new ReactiveAdapterRegistry(), false);