Search in sources :

Example 71 with ResolvableType

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));
}
Also used : ServerHttpMessageReader(org.springframework.http.codec.ServerHttpMessageReader) ServerHttpResponse(org.springframework.http.server.reactive.ServerHttpResponse) Validator(org.springframework.validation.Validator) Conventions(org.springframework.core.Conventions) WebExchangeDataBinder(org.springframework.web.bind.support.WebExchangeDataBinder) ServerWebInputException(org.springframework.web.server.ServerWebInputException) HttpMessageReader(org.springframework.http.codec.HttpMessageReader) BindingContext(org.springframework.web.reactive.BindingContext) ServerWebExchange(org.springframework.web.server.ServerWebExchange) HandlerMethodArgumentResolverSupport(org.springframework.web.reactive.result.method.HandlerMethodArgumentResolverSupport) UnsupportedMediaTypeStatusException(org.springframework.web.server.UnsupportedMediaTypeStatusException) Map(java.util.Map) MethodParameter(org.springframework.core.MethodParameter) ResolvableType(org.springframework.core.ResolvableType) ReactiveAdapterRegistry(org.springframework.core.ReactiveAdapterRegistry) WebExchangeBindException(org.springframework.web.bind.support.WebExchangeBindException) ServerHttpRequest(org.springframework.http.server.reactive.ServerHttpRequest) ReactiveAdapter(org.springframework.core.ReactiveAdapter) Validated(org.springframework.validation.annotation.Validated) AnnotationUtils(org.springframework.core.annotation.AnnotationUtils) MediaType(org.springframework.http.MediaType) Mono(reactor.core.publisher.Mono) Collectors(java.util.stream.Collectors) Flux(reactor.core.publisher.Flux) List(java.util.List) Annotation(java.lang.annotation.Annotation) Collections(java.util.Collections) Assert(org.springframework.util.Assert) ServerHttpRequest(org.springframework.http.server.reactive.ServerHttpRequest) ServerHttpResponse(org.springframework.http.server.reactive.ServerHttpResponse) ServerHttpMessageReader(org.springframework.http.codec.ServerHttpMessageReader) UnsupportedMediaTypeStatusException(org.springframework.web.server.UnsupportedMediaTypeStatusException) MediaType(org.springframework.http.MediaType) ResolvableType(org.springframework.core.ResolvableType) ReactiveAdapter(org.springframework.core.ReactiveAdapter)

Example 72 with ResolvableType

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);
    });
}
Also used : Publisher(org.reactivestreams.Publisher) MediaType(org.springframework.http.MediaType) HttpMessageReader(org.springframework.http.codec.HttpMessageReader) MultiValueMap(org.springframework.util.MultiValueMap) Mono(reactor.core.publisher.Mono) DataBuffer(org.springframework.core.io.buffer.DataBuffer) Function(java.util.function.Function) Supplier(java.util.function.Supplier) Collectors(java.util.stream.Collectors) Flux(reactor.core.publisher.Flux) List(java.util.List) Stream(java.util.stream.Stream) ReactiveHttpInputMessage(org.springframework.http.ReactiveHttpInputMessage) ResolvableType(org.springframework.core.ResolvableType) HttpMessage(org.springframework.http.HttpMessage) ServerHttpRequest(org.springframework.http.server.reactive.ServerHttpRequest) Assert(org.springframework.util.Assert) MediaType(org.springframework.http.MediaType) Stream(java.util.stream.Stream)

Example 73 with ResolvableType

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());
}
Also used : EncoderHttpMessageWriter(org.springframework.http.codec.EncoderHttpMessageWriter) HttpMessageWriter(org.springframework.http.codec.HttpMessageWriter) ResolvableType(org.springframework.core.ResolvableType) ServerHttpResponse(org.springframework.http.server.reactive.ServerHttpResponse)

Example 74 with ResolvableType

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));
    });
}
Also used : Locale(java.util.Locale) Model(org.springframework.ui.Model) ArrayList(java.util.ArrayList) List(java.util.List) ResolvableType(org.springframework.core.ResolvableType) MethodParameter(org.springframework.core.MethodParameter) ReactiveAdapter(org.springframework.core.ReactiveAdapter)

Example 75 with ResolvableType

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());
}
Also used : ServerWebExchange(org.springframework.web.server.ServerWebExchange) MockServerWebExchange(org.springframework.mock.http.server.reactive.test.MockServerWebExchange) CompletableFuture(java.util.concurrent.CompletableFuture) ResolvableType(org.springframework.core.ResolvableType) Test(org.junit.Test)

Aggregations

ResolvableType (org.springframework.core.ResolvableType)96 Test (org.junit.Test)66 MethodParameter (org.springframework.core.MethodParameter)20 DataBuffer (org.springframework.core.io.buffer.DataBuffer)15 ServerWebExchange (org.springframework.web.server.ServerWebExchange)14 List (java.util.List)11 MediaType (org.springframework.http.MediaType)10 Flux (reactor.core.publisher.Flux)10 Mono (reactor.core.publisher.Mono)10 Map (java.util.Map)9 Assert (org.springframework.util.Assert)7 Collections (java.util.Collections)6 MockServerWebExchange (org.springframework.mock.http.server.reactive.test.MockServerWebExchange)6 ArrayList (java.util.ArrayList)5 ReactiveAdapter (org.springframework.core.ReactiveAdapter)5 Pojo (org.springframework.http.codec.Pojo)5 ServerWebInputException (org.springframework.web.server.ServerWebInputException)5 Publisher (org.reactivestreams.Publisher)4 HttpMessageReader (org.springframework.http.codec.HttpMessageReader)4 Single (rx.Single)4