Skip to content

Commit 496223a

Browse files
committed
WebFlux supports field default/marker parameters for data classes as well
Issue: SPR-15871
1 parent cf106ec commit 496223a

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public Mono<Object> resolveArgument(
112112
ResolvableType valueType = (adapter != null ? type.getGeneric() : type);
113113

114114
Assert.state(adapter == null || !adapter.isMultiValue(),
115-
() -> getClass().getSimpleName() + " doesn't support multi-value reactive type wrapper: " +
115+
() -> getClass().getSimpleName() + " does not support multi-value reactive type wrapper: " +
116116
parameter.getGenericParameterType());
117117

118118
String name = getAttributeName(parameter);
@@ -169,7 +169,7 @@ private Mono<?> prepareAttributeMono(String attributeName, ResolvableType attrib
169169
if (attribute == null) {
170170
Class<?> attributeClass = attributeType.getRawClass();
171171
Assert.state(attributeClass != null, "No attribute class");
172-
return createAttribute(attributeName,attributeClass , context, exchange);
172+
return createAttribute(attributeName, attributeClass, context, exchange);
173173
}
174174

175175
ReactiveAdapter adapterFrom = getAdapterRegistry().getAdapter(null, attribute);
@@ -230,9 +230,23 @@ private Mono<?> createAttribute(
230230
() -> "Invalid number of parameter names: " + paramNames.length + " for constructor " + ctor);
231231
Object[] args = new Object[paramTypes.length];
232232
WebDataBinder binder = context.createDataBinder(exchange, null, attributeName);
233+
String fieldDefaultPrefix = binder.getFieldDefaultPrefix();
234+
String fieldMarkerPrefix = binder.getFieldMarkerPrefix();
233235
for (int i = 0; i < paramNames.length; i++) {
234-
Object value = bindValues.get(paramNames[i]);
235-
value = (value != null && value instanceof List ? ((List<?>) value).toArray() : value);
236+
String paramName = paramNames[i];
237+
Class<?> paramType = paramTypes[i];
238+
Object value = bindValues.get(paramName);
239+
if (value == null) {
240+
if (fieldDefaultPrefix != null) {
241+
value = bindValues.get(fieldDefaultPrefix + paramName);
242+
}
243+
if (value == null && fieldMarkerPrefix != null) {
244+
if (bindValues.get(fieldMarkerPrefix + paramName) != null) {
245+
value = binder.getEmptyValue(paramType);
246+
}
247+
}
248+
}
249+
value = (value instanceof List ? ((List<?>) value).toArray() : value);
236250
args[i] = binder.convertIfNecessary(value, paramTypes[i], new MethodParameter(ctor, i));
237251
}
238252
return BeanUtils.instantiateClass(ctor, args);

spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ private void testBindBar(MethodParameter param) throws Exception {
301301
assertTrue(map.get(bindingResultKey) instanceof BindingResult);
302302
}
303303

304+
// TODO: SPR-15871, SPR-15542
305+
304306

305307
private ModelAttributeMethodArgumentResolver createResolver() {
306308
return new ModelAttributeMethodArgumentResolver(new ReactiveAdapterRegistry(), false);

0 commit comments

Comments
 (0)