Search in sources :

Example 1 with ResolvableTypeProvider

use of org.springframework.core.ResolvableTypeProvider in project spring-framework by spring-projects.

the class MultipartHttpMessageWriter method encodePart.

@SuppressWarnings("unchecked")
private <T> Flux<DataBuffer> encodePart(byte[] boundary, String name, T value, DataBufferFactory factory) {
    MultipartHttpOutputMessage message = new MultipartHttpOutputMessage(factory);
    HttpHeaders headers = message.getHeaders();
    T body;
    ResolvableType resolvableType = null;
    if (value instanceof HttpEntity) {
        HttpEntity<T> httpEntity = (HttpEntity<T>) value;
        headers.putAll(httpEntity.getHeaders());
        body = httpEntity.getBody();
        Assert.state(body != null, "MultipartHttpMessageWriter only supports HttpEntity with body");
        if (httpEntity instanceof ResolvableTypeProvider) {
            resolvableType = ((ResolvableTypeProvider) httpEntity).getResolvableType();
        }
    } else {
        body = value;
    }
    if (resolvableType == null) {
        resolvableType = ResolvableType.forClass(body.getClass());
    }
    if (!headers.containsKey(HttpHeaders.CONTENT_DISPOSITION)) {
        if (body instanceof Resource) {
            headers.setContentDispositionFormData(name, ((Resource) body).getFilename());
        } else if (resolvableType.resolve() == Resource.class) {
            body = (T) Mono.from((Publisher<?>) body).doOnNext(o -> headers.setContentDispositionFormData(name, ((Resource) o).getFilename()));
        } else {
            headers.setContentDispositionFormData(name, null);
        }
    }
    MediaType contentType = headers.getContentType();
    final ResolvableType finalBodyType = resolvableType;
    Optional<HttpMessageWriter<?>> writer = this.partWriters.stream().filter(partWriter -> partWriter.canWrite(finalBodyType, contentType)).findFirst();
    if (!writer.isPresent()) {
        return Flux.error(new CodecException("No suitable writer found for part: " + name));
    }
    Publisher<T> bodyPublisher = body instanceof Publisher ? (Publisher<T>) body : Mono.just(body);
    // The writer will call MultipartHttpOutputMessage#write which doesn't actually write
    // but only stores the body Flux and returns Mono.empty().
    Mono<Void> partContentReady = ((HttpMessageWriter<T>) writer.get()).write(bodyPublisher, resolvableType, contentType, message, DEFAULT_HINTS);
    // After partContentReady, we can access the part content from MultipartHttpOutputMessage
    // and use it for writing to the actual request body
    Flux<DataBuffer> partContent = partContentReady.thenMany(Flux.defer(message::getBody));
    return Flux.concat(generateBoundaryLine(boundary, factory), partContent, generateNewLine(factory));
}
Also used : CharSequenceEncoder(org.springframework.core.codec.CharSequenceEncoder) Arrays(java.util.Arrays) ResourceHttpMessageWriter(org.springframework.http.codec.ResourceHttpMessageWriter) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Hints(org.springframework.core.codec.Hints) ResolvableTypeProvider(org.springframework.core.ResolvableTypeProvider) Supplier(java.util.function.Supplier) ReactiveHttpOutputMessage(org.springframework.http.ReactiveHttpOutputMessage) ArrayList(java.util.ArrayList) CodecException(org.springframework.core.codec.CodecException) LogFormatUtils(org.springframework.core.log.LogFormatUtils) EncoderHttpMessageWriter(org.springframework.http.codec.EncoderHttpMessageWriter) Map(java.util.Map) DataBufferUtils(org.springframework.core.io.buffer.DataBufferUtils) Nullable(org.springframework.lang.Nullable) ResolvableType(org.springframework.core.ResolvableType) Resource(org.springframework.core.io.Resource) HttpHeaders(org.springframework.http.HttpHeaders) FormHttpMessageWriter(org.springframework.http.codec.FormHttpMessageWriter) Publisher(org.reactivestreams.Publisher) MediaType(org.springframework.http.MediaType) PooledDataBuffer(org.springframework.core.io.buffer.PooledDataBuffer) MultiValueMap(org.springframework.util.MultiValueMap) Mono(reactor.core.publisher.Mono) DataBuffer(org.springframework.core.io.buffer.DataBuffer) Flux(reactor.core.publisher.Flux) List(java.util.List) HttpEntity(org.springframework.http.HttpEntity) DataBufferFactory(org.springframework.core.io.buffer.DataBufferFactory) Optional(java.util.Optional) Collections(java.util.Collections) HttpMessageWriter(org.springframework.http.codec.HttpMessageWriter) Assert(org.springframework.util.Assert) HttpHeaders(org.springframework.http.HttpHeaders) HttpEntity(org.springframework.http.HttpEntity) ResourceHttpMessageWriter(org.springframework.http.codec.ResourceHttpMessageWriter) EncoderHttpMessageWriter(org.springframework.http.codec.EncoderHttpMessageWriter) FormHttpMessageWriter(org.springframework.http.codec.FormHttpMessageWriter) HttpMessageWriter(org.springframework.http.codec.HttpMessageWriter) Resource(org.springframework.core.io.Resource) Publisher(org.reactivestreams.Publisher) MediaType(org.springframework.http.MediaType) CodecException(org.springframework.core.codec.CodecException) ResolvableType(org.springframework.core.ResolvableType) ResolvableTypeProvider(org.springframework.core.ResolvableTypeProvider) PooledDataBuffer(org.springframework.core.io.buffer.PooledDataBuffer) DataBuffer(org.springframework.core.io.buffer.DataBuffer)

Aggregations

ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 Supplier (java.util.function.Supplier)1 Publisher (org.reactivestreams.Publisher)1 ResolvableType (org.springframework.core.ResolvableType)1 ResolvableTypeProvider (org.springframework.core.ResolvableTypeProvider)1 CharSequenceEncoder (org.springframework.core.codec.CharSequenceEncoder)1 CodecException (org.springframework.core.codec.CodecException)1 Hints (org.springframework.core.codec.Hints)1 Resource (org.springframework.core.io.Resource)1 DataBuffer (org.springframework.core.io.buffer.DataBuffer)1 DataBufferFactory (org.springframework.core.io.buffer.DataBufferFactory)1 DataBufferUtils (org.springframework.core.io.buffer.DataBufferUtils)1 PooledDataBuffer (org.springframework.core.io.buffer.PooledDataBuffer)1 LogFormatUtils (org.springframework.core.log.LogFormatUtils)1