Search in sources :

Example 1 with ResolvableTypeProvider

use of cn.taketoday.core.ResolvableTypeProvider in project today-infrastructure by TAKETODAY.

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.fromClass(body.getClass());
    }
    if (!headers.containsKey(HttpHeaders.CONTENT_DISPOSITION)) {
        if (body instanceof Resource) {
            headers.setContentDispositionFormData(name, ((Resource) body).getName());
        } else if (resolvableType.resolve() == Resource.class) {
            body = (T) Mono.from((Publisher<?>) body).doOnNext(o -> headers.setContentDispositionFormData(name, ((Resource) o).getName()));
        } 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.isEmpty()) {
        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 : Arrays(java.util.Arrays) Assert(cn.taketoday.lang.Assert) ResolvableTypeProvider(cn.taketoday.core.ResolvableTypeProvider) DataBufferFactory(cn.taketoday.core.io.buffer.DataBufferFactory) Resource(cn.taketoday.core.io.Resource) FormHttpMessageWriter(cn.taketoday.http.codec.FormHttpMessageWriter) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CodecException(cn.taketoday.core.codec.CodecException) LogFormatUtils(cn.taketoday.util.LogFormatUtils) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HttpHeaders(cn.taketoday.http.HttpHeaders) ReactiveHttpOutputMessage(cn.taketoday.http.ReactiveHttpOutputMessage) DataBufferUtils(cn.taketoday.core.io.buffer.DataBufferUtils) PooledDataBuffer(cn.taketoday.core.io.buffer.PooledDataBuffer) Hints(cn.taketoday.core.codec.Hints) Map(java.util.Map) CharSequenceEncoder(cn.taketoday.core.codec.CharSequenceEncoder) DataBuffer(cn.taketoday.core.io.buffer.DataBuffer) MultiValueMap(cn.taketoday.core.MultiValueMap) EncoderHttpMessageWriter(cn.taketoday.http.codec.EncoderHttpMessageWriter) Publisher(org.reactivestreams.Publisher) ResolvableType(cn.taketoday.core.ResolvableType) HttpMessageWriter(cn.taketoday.http.codec.HttpMessageWriter) Mono(reactor.core.publisher.Mono) ResourceHttpMessageWriter(cn.taketoday.http.codec.ResourceHttpMessageWriter) Flux(reactor.core.publisher.Flux) List(java.util.List) Nullable(cn.taketoday.lang.Nullable) Optional(java.util.Optional) HttpEntity(cn.taketoday.http.HttpEntity) MediaType(cn.taketoday.http.MediaType) Collections(java.util.Collections) HttpHeaders(cn.taketoday.http.HttpHeaders) HttpEntity(cn.taketoday.http.HttpEntity) FormHttpMessageWriter(cn.taketoday.http.codec.FormHttpMessageWriter) EncoderHttpMessageWriter(cn.taketoday.http.codec.EncoderHttpMessageWriter) HttpMessageWriter(cn.taketoday.http.codec.HttpMessageWriter) ResourceHttpMessageWriter(cn.taketoday.http.codec.ResourceHttpMessageWriter) Resource(cn.taketoday.core.io.Resource) Publisher(org.reactivestreams.Publisher) MediaType(cn.taketoday.http.MediaType) CodecException(cn.taketoday.core.codec.CodecException) ResolvableType(cn.taketoday.core.ResolvableType) ResolvableTypeProvider(cn.taketoday.core.ResolvableTypeProvider) PooledDataBuffer(cn.taketoday.core.io.buffer.PooledDataBuffer) DataBuffer(cn.taketoday.core.io.buffer.DataBuffer)

Example 2 with ResolvableTypeProvider

use of cn.taketoday.core.ResolvableTypeProvider in project today-framework by TAKETODAY.

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.fromClass(body.getClass());
    }
    if (!headers.containsKey(HttpHeaders.CONTENT_DISPOSITION)) {
        if (body instanceof Resource) {
            headers.setContentDispositionFormData(name, ((Resource) body).getName());
        } else if (resolvableType.resolve() == Resource.class) {
            body = (T) Mono.from((Publisher<?>) body).doOnNext(o -> headers.setContentDispositionFormData(name, ((Resource) o).getName()));
        } 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.isEmpty()) {
        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 : Arrays(java.util.Arrays) Assert(cn.taketoday.lang.Assert) ResolvableTypeProvider(cn.taketoday.core.ResolvableTypeProvider) DataBufferFactory(cn.taketoday.core.io.buffer.DataBufferFactory) Resource(cn.taketoday.core.io.Resource) FormHttpMessageWriter(cn.taketoday.http.codec.FormHttpMessageWriter) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CodecException(cn.taketoday.core.codec.CodecException) LogFormatUtils(cn.taketoday.util.LogFormatUtils) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HttpHeaders(cn.taketoday.http.HttpHeaders) ReactiveHttpOutputMessage(cn.taketoday.http.ReactiveHttpOutputMessage) DataBufferUtils(cn.taketoday.core.io.buffer.DataBufferUtils) PooledDataBuffer(cn.taketoday.core.io.buffer.PooledDataBuffer) Hints(cn.taketoday.core.codec.Hints) Map(java.util.Map) CharSequenceEncoder(cn.taketoday.core.codec.CharSequenceEncoder) DataBuffer(cn.taketoday.core.io.buffer.DataBuffer) MultiValueMap(cn.taketoday.core.MultiValueMap) EncoderHttpMessageWriter(cn.taketoday.http.codec.EncoderHttpMessageWriter) Publisher(org.reactivestreams.Publisher) ResolvableType(cn.taketoday.core.ResolvableType) HttpMessageWriter(cn.taketoday.http.codec.HttpMessageWriter) Mono(reactor.core.publisher.Mono) ResourceHttpMessageWriter(cn.taketoday.http.codec.ResourceHttpMessageWriter) Flux(reactor.core.publisher.Flux) List(java.util.List) Nullable(cn.taketoday.lang.Nullable) Optional(java.util.Optional) HttpEntity(cn.taketoday.http.HttpEntity) MediaType(cn.taketoday.http.MediaType) Collections(java.util.Collections) HttpHeaders(cn.taketoday.http.HttpHeaders) HttpEntity(cn.taketoday.http.HttpEntity) FormHttpMessageWriter(cn.taketoday.http.codec.FormHttpMessageWriter) EncoderHttpMessageWriter(cn.taketoday.http.codec.EncoderHttpMessageWriter) HttpMessageWriter(cn.taketoday.http.codec.HttpMessageWriter) ResourceHttpMessageWriter(cn.taketoday.http.codec.ResourceHttpMessageWriter) Resource(cn.taketoday.core.io.Resource) Publisher(org.reactivestreams.Publisher) MediaType(cn.taketoday.http.MediaType) CodecException(cn.taketoday.core.codec.CodecException) ResolvableType(cn.taketoday.core.ResolvableType) ResolvableTypeProvider(cn.taketoday.core.ResolvableTypeProvider) PooledDataBuffer(cn.taketoday.core.io.buffer.PooledDataBuffer) DataBuffer(cn.taketoday.core.io.buffer.DataBuffer)

Aggregations

MultiValueMap (cn.taketoday.core.MultiValueMap)2 ResolvableType (cn.taketoday.core.ResolvableType)2 ResolvableTypeProvider (cn.taketoday.core.ResolvableTypeProvider)2 CharSequenceEncoder (cn.taketoday.core.codec.CharSequenceEncoder)2 CodecException (cn.taketoday.core.codec.CodecException)2 Hints (cn.taketoday.core.codec.Hints)2 Resource (cn.taketoday.core.io.Resource)2 DataBuffer (cn.taketoday.core.io.buffer.DataBuffer)2 DataBufferFactory (cn.taketoday.core.io.buffer.DataBufferFactory)2 DataBufferUtils (cn.taketoday.core.io.buffer.DataBufferUtils)2 PooledDataBuffer (cn.taketoday.core.io.buffer.PooledDataBuffer)2 HttpEntity (cn.taketoday.http.HttpEntity)2 HttpHeaders (cn.taketoday.http.HttpHeaders)2 MediaType (cn.taketoday.http.MediaType)2 ReactiveHttpOutputMessage (cn.taketoday.http.ReactiveHttpOutputMessage)2 EncoderHttpMessageWriter (cn.taketoday.http.codec.EncoderHttpMessageWriter)2 FormHttpMessageWriter (cn.taketoday.http.codec.FormHttpMessageWriter)2 HttpMessageWriter (cn.taketoday.http.codec.HttpMessageWriter)2 ResourceHttpMessageWriter (cn.taketoday.http.codec.ResourceHttpMessageWriter)2 Assert (cn.taketoday.lang.Assert)2