use of org.springframework.web.reactive.result.method.InvocableHandlerMethod 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.result.method.InvocableHandlerMethod in project spring-framework by spring-projects.
the class RequestMappingHandlerAdapter method getExceptionHandlerMethod.
private InvocableHandlerMethod getExceptionHandlerMethod(Throwable ex, HandlerMethod handlerMethod) {
Class<?> handlerType = handlerMethod.getBeanType();
ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.computeIfAbsent(handlerType, ExceptionHandlerMethodResolver::new);
return Optional.ofNullable(resolver.resolveMethodByThrowable(ex)).map(method -> createHandlerMethod(handlerMethod.getBean(), method)).orElseGet(() -> this.exceptionHandlerAdviceCache.entrySet().stream().map(entry -> {
if (entry.getKey().isApplicableToBeanType(handlerType)) {
Method method = entry.getValue().resolveMethodByThrowable(ex);
if (method != null) {
Object bean = entry.getKey().resolveBean();
return createHandlerMethod(bean, method);
}
}
return null;
}).filter(Objects::nonNull).findFirst().orElse(null));
}
use of org.springframework.web.reactive.result.method.InvocableHandlerMethod 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.result.method.InvocableHandlerMethod in project spring-framework by spring-projects.
the class ModelInitializerTests method toInvocable.
private InvocableHandlerMethod toInvocable(Object controller, Method method) {
ModelArgumentResolver resolver = new ModelArgumentResolver(new ReactiveAdapterRegistry());
InvocableHandlerMethod handlerMethod = new InvocableHandlerMethod(controller, method);
handlerMethod.setArgumentResolvers(Collections.singletonList(resolver));
return handlerMethod;
}
use of org.springframework.web.reactive.result.method.InvocableHandlerMethod in project spring-framework by spring-projects.
the class RequestMappingHandlerAdapter method handleException.
private Mono<HandlerResult> handleException(ServerWebExchange exchange, HandlerMethod handlerMethod, BindingContext bindingContext, Throwable ex) {
InvocableHandlerMethod invocable = getExceptionHandlerMethod(ex, handlerMethod);
if (invocable != null) {
try {
if (logger.isDebugEnabled()) {
logger.debug("Invoking @ExceptionHandler method: " + invocable.getMethod());
}
bindingContext.getModel().asMap().clear();
Throwable cause = ex.getCause() != null ? ex.getCause() : ex;
return invocable.invoke(exchange, bindingContext, cause, handlerMethod);
} catch (Throwable invocationEx) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to invoke: " + invocable.getMethod(), invocationEx);
}
}
}
return Mono.error(ex);
}
Aggregations