use of org.springframework.core.ResolvableType in project spring-framework by spring-projects.
the class AbstractMessageReaderArgumentResolver method readBody.
protected Mono<Object> readBody(MethodParameter bodyParameter, boolean isBodyRequired, BindingContext bindingContext, ServerWebExchange exchange) {
ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParameter);
ReactiveAdapter adapter = getAdapterRegistry().getAdapter(bodyType.resolve());
ResolvableType elementType = (adapter != null ? bodyType.getGeneric(0) : bodyType);
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
MediaType mediaType = request.getHeaders().getContentType();
if (mediaType == null) {
mediaType = MediaType.APPLICATION_OCTET_STREAM;
}
for (HttpMessageReader<?> reader : getMessageReaders()) {
if (reader.canRead(elementType, mediaType)) {
Map<String, Object> readHints = Collections.emptyMap();
if (adapter != null && adapter.isMultiValue()) {
Flux<?> flux;
if (reader instanceof ServerHttpMessageReader) {
ServerHttpMessageReader<?> serverReader = ((ServerHttpMessageReader<?>) reader);
flux = serverReader.read(bodyType, elementType, request, response, readHints);
} else {
flux = reader.read(elementType, request, readHints);
}
flux = flux.onErrorResumeWith(ex -> Flux.error(getReadError(bodyParameter, ex)));
if (isBodyRequired || !adapter.supportsEmpty()) {
flux = flux.switchIfEmpty(Flux.error(getRequiredBodyError(bodyParameter)));
}
Object[] hints = extractValidationHints(bodyParameter);
if (hints != null) {
flux = flux.doOnNext(target -> validate(target, hints, bodyParameter, bindingContext, exchange));
}
return Mono.just(adapter.fromPublisher(flux));
} else {
Mono<?> mono;
if (reader instanceof ServerHttpMessageReader) {
ServerHttpMessageReader<?> serverReader = (ServerHttpMessageReader<?>) reader;
mono = serverReader.readMono(bodyType, elementType, request, response, readHints);
} else {
mono = reader.readMono(elementType, request, readHints);
}
mono = mono.otherwise(ex -> Mono.error(getReadError(bodyParameter, ex)));
if (isBodyRequired || (adapter != null && !adapter.supportsEmpty())) {
mono = mono.otherwiseIfEmpty(Mono.error(getRequiredBodyError(bodyParameter)));
}
Object[] hints = extractValidationHints(bodyParameter);
if (hints != null) {
mono = mono.doOnNext(target -> validate(target, hints, bodyParameter, bindingContext, exchange));
}
if (adapter != null) {
return Mono.just(adapter.fromPublisher(mono));
} else {
return Mono.from(mono);
}
}
}
}
return Mono.error(new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes));
}
use of org.springframework.core.ResolvableType in project spring-framework by spring-projects.
the class BodyExtractors method readWithMessageReaders.
private static <T, S extends Publisher<T>> S readWithMessageReaders(ReactiveHttpInputMessage inputMessage, BodyExtractor.Context context, ResolvableType elementType, Function<HttpMessageReader<T>, S> readerFunction, Function<Throwable, S> unsupportedError) {
MediaType contentType = contentType(inputMessage);
Supplier<Stream<HttpMessageReader<?>>> messageReaders = context.messageReaders();
return messageReaders.get().filter(r -> r.canRead(elementType, contentType)).findFirst().map(BodyExtractors::<T>cast).map(readerFunction).orElseGet(() -> {
List<MediaType> supportedMediaTypes = messageReaders.get().flatMap(reader -> reader.getReadableMediaTypes().stream()).collect(Collectors.toList());
UnsupportedMediaTypeException error = new UnsupportedMediaTypeException(contentType, supportedMediaTypes);
return unsupportedError.apply(error);
});
}
use of org.springframework.core.ResolvableType in project spring-framework by spring-projects.
the class HttpMessageWriterView method applyMessageWriter.
@SuppressWarnings("unchecked")
private <T> Mono<Void> applyMessageWriter(Object value, MediaType contentType, ServerWebExchange exchange) {
if (value == null) {
return Mono.empty();
}
Publisher<? extends T> stream = Mono.just((T) value);
ResolvableType type = ResolvableType.forClass(value.getClass());
ServerHttpResponse response = exchange.getResponse();
return ((HttpMessageWriter<T>) getMessageWriter()).write(stream, type, contentType, response, Collections.emptyMap());
}
use of org.springframework.core.ResolvableType in project spring-framework by spring-projects.
the class ViewResolutionResultHandler method handleResult.
@Override
@SuppressWarnings("unchecked")
public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
Mono<Object> valueMono;
ResolvableType valueType;
ReactiveAdapter adapter = getAdapter(result);
if (adapter != null) {
Assert.isTrue(!adapter.isMultiValue(), "Only single-value async return type supported.");
valueMono = result.getReturnValue().map(value -> Mono.from(adapter.toPublisher(value))).orElse(Mono.empty());
valueType = adapter.isNoValue() ? ResolvableType.forClass(Void.class) : result.getReturnType().getGeneric(0);
} else {
valueMono = Mono.justOrEmpty(result.getReturnValue());
valueType = result.getReturnType();
}
return valueMono.otherwiseIfEmpty(exchange.isNotModified() ? Mono.empty() : NO_VALUE_MONO).then(returnValue -> {
Mono<List<View>> viewsMono;
Model model = result.getModel();
MethodParameter parameter = result.getReturnTypeSource();
Locale acceptLocale = exchange.getRequest().getHeaders().getAcceptLanguageAsLocale();
Locale locale = acceptLocale != null ? acceptLocale : Locale.getDefault();
Class<?> clazz = valueType.getRawClass();
if (clazz == null) {
clazz = returnValue.getClass();
}
if (returnValue == NO_VALUE || Void.class.equals(clazz) || void.class.equals(clazz)) {
viewsMono = resolveViews(getDefaultViewName(exchange), locale);
} else if (Model.class.isAssignableFrom(clazz)) {
model.addAllAttributes(((Model) returnValue).asMap());
viewsMono = resolveViews(getDefaultViewName(exchange), locale);
} else if (Map.class.isAssignableFrom(clazz)) {
model.addAllAttributes((Map<String, ?>) returnValue);
viewsMono = resolveViews(getDefaultViewName(exchange), locale);
} else if (View.class.isAssignableFrom(clazz)) {
viewsMono = Mono.just(Collections.singletonList((View) returnValue));
} else if (CharSequence.class.isAssignableFrom(clazz) && !hasModelAnnotation(parameter)) {
viewsMono = resolveViews(returnValue.toString(), locale);
} else {
String name = getNameForReturnValue(clazz, parameter);
model.addAttribute(name, returnValue);
viewsMono = resolveViews(getDefaultViewName(exchange), locale);
}
return resolveAsyncAttributes(model.asMap()).doOnSuccess(aVoid -> addBindingResult(result.getBindingContext(), exchange)).then(viewsMono).then(views -> render(views, model.asMap(), exchange));
});
}
use of org.springframework.core.ResolvableType in project spring-framework by spring-projects.
the class HttpEntityArgumentResolverTests method httpEntityWithCompletableFutureBody.
@Test
public void httpEntityWithCompletableFutureBody() throws Exception {
ServerWebExchange exchange = postExchange("line1");
ResolvableType type = httpEntityType(CompletableFuture.class, String.class);
HttpEntity<CompletableFuture<String>> httpEntity = resolveValue(exchange, type);
assertEquals(exchange.getRequest().getHeaders(), httpEntity.getHeaders());
assertEquals("line1", httpEntity.getBody().get());
}
Aggregations