use of org.springframework.web.reactive.BindingContext in project spring-framework by spring-projects.
the class ModelAttributeMethodArgumentResolver method resolveArgument.
@Override
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext context, ServerWebExchange exchange) {
ResolvableType type = ResolvableType.forMethodParameter(parameter);
ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type.resolve());
ResolvableType valueType = (adapter != null ? type.getGeneric(0) : type);
Assert.state(adapter == null || !adapter.isMultiValue(), getClass().getSimpleName() + " doesn't support multi-value reactive type wrapper: " + parameter.getGenericParameterType());
String name = getAttributeName(valueType, parameter);
Mono<?> valueMono = getAttributeMono(name, valueType, context.getModel());
Map<String, Object> model = context.getModel().asMap();
MonoProcessor<BindingResult> bindingResultMono = MonoProcessor.create();
model.put(BindingResult.MODEL_KEY_PREFIX + name, bindingResultMono);
return valueMono.then(value -> {
WebExchangeDataBinder binder = context.createDataBinder(exchange, value, name);
return binder.bind(exchange).doOnError(bindingResultMono::onError).doOnSuccess(aVoid -> {
validateIfApplicable(binder, parameter);
BindingResult errors = binder.getBindingResult();
model.put(BindingResult.MODEL_KEY_PREFIX + name, errors);
model.put(name, value);
bindingResultMono.onNext(errors);
}).then(Mono.fromCallable(() -> {
BindingResult errors = binder.getBindingResult();
if (adapter != null) {
return adapter.fromPublisher(errors.hasErrors() ? Mono.error(new WebExchangeBindException(parameter, errors)) : valueMono);
} else {
if (errors.hasErrors() && !hasErrorsArgument(parameter)) {
throw new WebExchangeBindException(parameter, errors);
}
return value;
}
}));
});
}
use of org.springframework.web.reactive.BindingContext in project spring-framework by spring-projects.
the class RequestMappingHandlerAdapter method handle.
@Override
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
Assert.notNull(handler, "Expected handler");
HandlerMethod handlerMethod = (HandlerMethod) handler;
BindingContext bindingContext = new InitBinderBindingContext(getWebBindingInitializer(), getBinderMethods(handlerMethod));
return this.modelInitializer.initModel(bindingContext, getAttributeMethods(handlerMethod), exchange).then(() -> {
Function<Throwable, Mono<HandlerResult>> exceptionHandler = ex -> handleException(exchange, handlerMethod, bindingContext, ex);
InvocableHandlerMethod invocable = new InvocableHandlerMethod(handlerMethod);
invocable.setArgumentResolvers(getArgumentResolvers());
return invocable.invoke(exchange, bindingContext).doOnNext(result -> result.setExceptionHandler(exceptionHandler)).otherwise(exceptionHandler);
});
}
use of org.springframework.web.reactive.BindingContext in project spring-framework by spring-projects.
the class ViewResolutionResultHandler method addBindingResult.
private void addBindingResult(BindingContext context, ServerWebExchange exchange) {
Map<String, Object> model = context.getModel().asMap();
model.keySet().stream().filter(name -> isBindingCandidate(name, model.get(name))).filter(name -> !model.containsKey(BindingResult.MODEL_KEY_PREFIX + name)).forEach(name -> {
WebExchangeDataBinder binder = context.createDataBinder(exchange, model.get(name), name);
model.put(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
});
}
use of org.springframework.web.reactive.BindingContext in project spring-framework by spring-projects.
the class ModelInitializerTests method basic.
@SuppressWarnings("unchecked")
@Test
public void basic() throws Exception {
TestController controller = new TestController();
Validator validator = mock(Validator.class);
controller.setValidator(validator);
List<SyncInvocableHandlerMethod> binderMethods = getBinderMethods(controller);
List<InvocableHandlerMethod> attributeMethods = getAttributeMethods(controller);
WebBindingInitializer bindingInitializer = new ConfigurableWebBindingInitializer();
BindingContext bindingContext = new InitBinderBindingContext(bindingInitializer, binderMethods);
this.modelInitializer.initModel(bindingContext, attributeMethods, this.exchange).block(Duration.ofMillis(5000));
WebExchangeDataBinder binder = bindingContext.createDataBinder(this.exchange, "name");
assertEquals(Collections.singletonList(validator), binder.getValidators());
Map<String, Object> model = bindingContext.getModel().asMap();
assertEquals(5, model.size());
Object value = model.get("bean");
assertEquals("Bean", ((TestBean) value).getName());
value = model.get("monoBean");
assertEquals("Mono Bean", ((Mono<TestBean>) value).block(Duration.ofMillis(5000)).getName());
value = model.get("singleBean");
assertEquals("Single Bean", ((Single<TestBean>) value).toBlocking().value().getName());
value = model.get("voidMethodBean");
assertEquals("Void Method Bean", ((TestBean) value).getName());
value = model.get("voidMonoMethodBean");
assertEquals("Void Mono Method Bean", ((TestBean) value).getName());
}
use of org.springframework.web.reactive.BindingContext in project spring-framework by spring-projects.
the class PathVariableMapMethodArgumentResolverTests method resolveArgumentNoUriVars.
@Test
public void resolveArgumentNoUriVars() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(this.paramMap, new BindingContext(), this.exchange);
Object result = mono.block();
assertEquals(Collections.emptyMap(), result);
}
Aggregations