Improve resolution of multi-value async model attrs
Multi-value async attributes like Flux and Observable in the model are treated with Collection semantics and resolved to Mono<List<?>> prior to rendering.
This commit is contained in:
parent
bb702ee9c0
commit
a224874b43
|
@ -294,13 +294,20 @@ public class ViewResolutionResultHandler extends AbstractHandlerResultHandler
|
||||||
private Mono<Void> resolveAsyncAttributes(Map<String, Object> model) {
|
private Mono<Void> resolveAsyncAttributes(Map<String, Object> model) {
|
||||||
|
|
||||||
List<String> names = new ArrayList<>();
|
List<String> names = new ArrayList<>();
|
||||||
List<Mono<Object>> valueMonos = new ArrayList<>();
|
List<Mono<?>> valueMonos = new ArrayList<>();
|
||||||
|
|
||||||
for (Map.Entry<String, ?> entry : model.entrySet()) {
|
for (Map.Entry<String, ?> entry : model.entrySet()) {
|
||||||
ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(null, entry.getValue());
|
ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(null, entry.getValue());
|
||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
names.add(entry.getKey());
|
names.add(entry.getKey());
|
||||||
valueMonos.add(adapter.toMono(entry.getValue()).defaultIfEmpty(NO_VALUE));
|
if (adapter.getDescriptor().isMultiValue()) {
|
||||||
|
Flux<Object> value = adapter.toFlux(entry.getValue());
|
||||||
|
valueMonos.add(value.collectList().defaultIfEmpty(Collections.emptyList()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Mono<Object> value = adapter.toMono(entry.getValue());
|
||||||
|
valueMonos.add(value.defaultIfEmpty(NO_VALUE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
import rx.Completable;
|
import rx.Completable;
|
||||||
|
import rx.Observable;
|
||||||
import rx.Single;
|
import rx.Single;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
|
@ -270,9 +271,11 @@ public class ViewResolutionResultHandlerTests {
|
||||||
@Test
|
@Test
|
||||||
public void modelWithAsyncAttributes() throws Exception {
|
public void modelWithAsyncAttributes() throws Exception {
|
||||||
this.bindingContext.getModel()
|
this.bindingContext.getModel()
|
||||||
.addAttribute("bean1", Mono.just(new TestBean("Bean1")))
|
.addAttribute("attr1", Mono.just(new TestBean("Bean1")))
|
||||||
.addAttribute("bean2", Single.just(new TestBean("Bean2")))
|
.addAttribute("attr2", Flux.just(new TestBean("Bean1"), new TestBean("Bean2")))
|
||||||
.addAttribute("empty", Mono.empty());
|
.addAttribute("attr3", Single.just(new TestBean("Bean2")))
|
||||||
|
.addAttribute("attr4", Observable.just(new TestBean("Bean1"), new TestBean("Bean2")))
|
||||||
|
.addAttribute("attr5", Mono.empty());
|
||||||
|
|
||||||
ResolvableType type = forClass(void.class);
|
ResolvableType type = forClass(void.class);
|
||||||
HandlerResult result = new HandlerResult(new Object(), null, returnType(type), this.bindingContext);
|
HandlerResult result = new HandlerResult(new Object(), null, returnType(type), this.bindingContext);
|
||||||
|
@ -281,11 +284,13 @@ public class ViewResolutionResultHandlerTests {
|
||||||
this.request.setUri("/account");
|
this.request.setUri("/account");
|
||||||
handler.handleResult(this.exchange, result).blockMillis(5000);
|
handler.handleResult(this.exchange, result).blockMillis(5000);
|
||||||
assertResponseBody("account: {" +
|
assertResponseBody("account: {" +
|
||||||
"bean1=TestBean[name=Bean1], " +
|
"attr1=TestBean[name=Bean1], " +
|
||||||
"bean2=TestBean[name=Bean2], " +
|
"attr2=[TestBean[name=Bean1], TestBean[name=Bean2]], " +
|
||||||
"org.springframework.validation.BindingResult.bean1=" +
|
"attr3=TestBean[name=Bean2], " +
|
||||||
|
"attr4=[TestBean[name=Bean1], TestBean[name=Bean2]], " +
|
||||||
|
"org.springframework.validation.BindingResult.attr1=" +
|
||||||
"org.springframework.validation.BeanPropertyBindingResult: 0 errors, " +
|
"org.springframework.validation.BeanPropertyBindingResult: 0 errors, " +
|
||||||
"org.springframework.validation.BindingResult.bean2=" +
|
"org.springframework.validation.BindingResult.attr3=" +
|
||||||
"org.springframework.validation.BeanPropertyBindingResult: 0 errors" +
|
"org.springframework.validation.BeanPropertyBindingResult: 0 errors" +
|
||||||
"}");
|
"}");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue