/** * Constructor with an {@code Encoder}. */ public HttpMessageWriterView(Encoder<?> encoder) { this(new EncoderHttpMessageWriter<>(encoder)); }
@Nullable private MediaType updateContentType(ReactiveHttpOutputMessage message, @Nullable MediaType mediaType) { MediaType result = message.getHeaders().getContentType(); if (result != null) { return result; } MediaType fallback = this.defaultMediaType; result = (useFallback(mediaType, fallback) ? fallback : mediaType); if (result != null) { result = addDefaultCharset(result, fallback); message.getHeaders().setContentType(result); } return result; }
@Override public Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType actualType, ResolvableType elementType, @Nullable MediaType mediaType, ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> hints) { Map<String, Object> allHints = Hints.merge(hints, getWriteHints(actualType, elementType, mediaType, request, response)); return write(inputStream, elementType, mediaType, response, allHints); }
/** * Create an instance wrapping the given {@link Encoder}. */ public EncoderHttpMessageWriter(Encoder<T> encoder) { Assert.notNull(encoder, "Encoder is required"); initLogger(encoder); this.encoder = encoder; this.mediaTypes = MediaType.asMediaTypes(encoder.getEncodableMimeTypes()); this.defaultMediaType = initDefaultMediaType(this.mediaTypes); }
@Nullable MediaType mediaType, ReactiveHttpOutputMessage message, Map<String, Object> hints) { MediaType contentType = updateContentType(message, mediaType); return (isStreamingMediaType(contentType) ? message.writeAndFlushWith(body.map(Flux::just)) : message.writeWith(body)); allHints.putAll(getWriteHints(actualType, elementType, mediaType, request, response)); allHints.putAll(hints); return write(inputStream, elementType, mediaType, response, allHints);
@SuppressWarnings("unchecked") @Override public Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage message, Map<String, Object> hints) { MediaType contentType = updateContentType(message, mediaType); Flux<DataBuffer> body = this.encoder.encode( inputStream, message.bufferFactory(), elementType, contentType, hints); if (inputStream instanceof Mono) { HttpHeaders headers = message.getHeaders(); return Mono.from(body) .switchIfEmpty(Mono.defer(() -> { headers.setContentLength(0); return message.setComplete().then(Mono.empty()); })) .flatMap(buffer -> { headers.setContentLength(buffer.readableByteCount()); return message.writeWith(Mono.just(buffer)); }); } return (isStreamingMediaType(contentType) ? message.writeAndFlushWith(body.map(Flux::just)) : message.writeWith(body)); }
@SuppressWarnings("unchecked") @Override public Mono<Void> write(Publisher<? extends Message> inputStream, ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage message, Map<String, Object> hints) { try { Message.Builder builder = getMessageBuilder(elementType.toClass()); Descriptors.Descriptor descriptor = builder.getDescriptorForType(); message.getHeaders().add(X_PROTOBUF_SCHEMA_HEADER, descriptor.getFile().getName()); message.getHeaders().add(X_PROTOBUF_MESSAGE_HEADER, descriptor.getFullName()); if (inputStream instanceof Flux) { if (mediaType == null) { message.getHeaders().setContentType(((HttpMessageEncoder<?>)getEncoder()).getStreamingMediaTypes().get(0)); } else if (!ProtobufEncoder.DELIMITED_VALUE.equals(mediaType.getParameters().get(ProtobufEncoder.DELIMITED_KEY))) { Map<String, String> parameters = new HashMap<>(mediaType.getParameters()); parameters.put(ProtobufEncoder.DELIMITED_KEY, ProtobufEncoder.DELIMITED_VALUE); message.getHeaders().setContentType(new MediaType(mediaType.getType(), mediaType.getSubtype(), parameters)); } } return super.write(inputStream, elementType, mediaType, message, hints); } catch (Exception ex) { return Mono.error(new DecodingException("Could not read Protobuf message: " + ex.getMessage(), ex)); } }
/** * Create an instance wrapping the given {@link Encoder}. */ public EncoderHttpMessageWriter(Encoder<T> encoder) { Assert.notNull(encoder, "Encoder is required"); this.encoder = encoder; this.mediaTypes = MediaType.asMediaTypes(encoder.getEncodableMimeTypes()); this.defaultMediaType = initDefaultMediaType(this.mediaTypes); }
/** * Create an instance wrapping the given {@link Encoder}. */ public EncoderHttpMessageWriter(Encoder<T> encoder) { Assert.notNull(encoder, "Encoder is required"); this.encoder = encoder; this.mediaTypes = MediaType.asMediaTypes(encoder.getEncodableMimeTypes()); this.defaultMediaType = initDefaultMediaType(this.mediaTypes); initLogger(encoder); }
@SuppressWarnings("unchecked") @Override public Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage message, Map<String, Object> hints) { MediaType contentType = updateContentType(message, mediaType); Flux<DataBuffer> body = this.encoder.encode( inputStream, message.bufferFactory(), elementType, contentType, hints); if (inputStream instanceof Mono) { HttpHeaders headers = message.getHeaders(); return Mono.from(body) .switchIfEmpty(Mono.defer(() -> { headers.setContentLength(0); return message.setComplete().then(Mono.empty()); })) .flatMap(buffer -> { headers.setContentLength(buffer.readableByteCount()); return message.writeWith(Mono.just(buffer)); }); } return (isStreamingMediaType(contentType) ? message.writeAndFlushWith(body.map(Flux::just)) : message.writeWith(body)); }
@SuppressWarnings("unchecked") @Override public Mono<Void> write(Publisher<? extends Message> inputStream, ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage message, Map<String, Object> hints) { try { Message.Builder builder = getMessageBuilder(elementType.toClass()); Descriptors.Descriptor descriptor = builder.getDescriptorForType(); message.getHeaders().add(X_PROTOBUF_SCHEMA_HEADER, descriptor.getFile().getName()); message.getHeaders().add(X_PROTOBUF_MESSAGE_HEADER, descriptor.getFullName()); if (inputStream instanceof Flux) { if (mediaType == null) { message.getHeaders().setContentType(((HttpMessageEncoder<?>)getEncoder()).getStreamingMediaTypes().get(0)); } else if (!ProtobufEncoder.DELIMITED_VALUE.equals(mediaType.getParameters().get(ProtobufEncoder.DELIMITED_KEY))) { Map<String, String> parameters = new HashMap<>(mediaType.getParameters()); parameters.put(ProtobufEncoder.DELIMITED_KEY, ProtobufEncoder.DELIMITED_VALUE); message.getHeaders().setContentType(new MediaType(mediaType.getType(), mediaType.getSubtype(), parameters)); } } return super.write(inputStream, elementType, mediaType, message, hints); } catch (Exception ex) { return Mono.error(new DecodingException("Could not read Protobuf message: " + ex.getMessage(), ex)); } }
/** * Return writers that need to be at the end, after all others. */ List<HttpMessageWriter<?>> getCatchAllWriters() { if (!this.registerDefaults) { return Collections.emptyList(); } List<HttpMessageWriter<?>> result = new ArrayList<>(); result.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes())); return result; }
@Nullable private MediaType updateContentType(ReactiveHttpOutputMessage message, @Nullable MediaType mediaType) { MediaType result = message.getHeaders().getContentType(); if (result != null) { return result; } MediaType fallback = this.defaultMediaType; result = (useFallback(mediaType, fallback) ? fallback : mediaType); if (result != null) { result = addDefaultCharset(result, fallback); message.getHeaders().setContentType(result); } return result; }
/** * Create an instance wrapping the given {@link Encoder}. */ public EncoderHttpMessageWriter(Encoder<T> encoder) { Assert.notNull(encoder, "Encoder is required"); this.encoder = encoder; this.mediaTypes = MediaType.asMediaTypes(encoder.getEncodableMimeTypes()); this.defaultMediaType = initDefaultMediaType(this.mediaTypes); initLogger(encoder); }
@Override public Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType actualType, ResolvableType elementType, @Nullable MediaType mediaType, ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> hints) { Map<String, Object> allHints = Hints.merge(hints, getWriteHints(actualType, elementType, mediaType, request, response)); return write(inputStream, elementType, mediaType, response, allHints); }
@SuppressWarnings("unchecked") @Override public Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage message, Map<String, Object> hints) { MediaType contentType = updateContentType(message, mediaType); Flux<DataBuffer> body = this.encoder.encode( inputStream, message.bufferFactory(), elementType, contentType, hints); if (inputStream instanceof Mono) { HttpHeaders headers = message.getHeaders(); return Mono.from(body) .switchIfEmpty(Mono.defer(() -> { headers.setContentLength(0); return message.setComplete().then(Mono.empty()); })) .flatMap(buffer -> { headers.setContentLength(buffer.readableByteCount()); return message.writeWith(Mono.just(buffer)); }); } return (isStreamingMediaType(contentType) ? message.writeAndFlushWith(body.map(Flux::just)) : message.writeWith(body)); }
@SuppressWarnings("unchecked") @Override public Mono<Void> write(Publisher<? extends Message> inputStream, ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage message, Map<String, Object> hints) { try { Message.Builder builder = getMessageBuilder(elementType.toClass()); Descriptors.Descriptor descriptor = builder.getDescriptorForType(); message.getHeaders().add(X_PROTOBUF_SCHEMA_HEADER, descriptor.getFile().getName()); message.getHeaders().add(X_PROTOBUF_MESSAGE_HEADER, descriptor.getFullName()); if (inputStream instanceof Flux) { if (mediaType == null) { message.getHeaders().setContentType(((HttpMessageEncoder<?>)getEncoder()).getStreamingMediaTypes().get(0)); } else if (!ProtobufEncoder.DELIMITED_VALUE.equals(mediaType.getParameters().get(ProtobufEncoder.DELIMITED_KEY))) { Map<String, String> parameters = new HashMap<>(mediaType.getParameters()); parameters.put(ProtobufEncoder.DELIMITED_KEY, ProtobufEncoder.DELIMITED_VALUE); message.getHeaders().setContentType(new MediaType(mediaType.getType(), mediaType.getSubtype(), parameters)); } } return super.write(inputStream, elementType, mediaType, message, hints); } catch (Exception ex) { return Mono.error(new DecodingException("Could not read Protobuf message: " + ex.getMessage(), ex)); } }
@Override public ClientCodecConfigurer.MultipartCodecs encoder(Encoder<?> encoder) { writer(new EncoderHttpMessageWriter<>(encoder)); return this; }
@Nullable private MediaType updateContentType(ReactiveHttpOutputMessage message, @Nullable MediaType mediaType) { MediaType result = message.getHeaders().getContentType(); if (result != null) { return result; } MediaType fallback = this.defaultMediaType; result = (useFallback(mediaType, fallback) ? fallback : mediaType); if (result != null) { result = addDefaultCharset(result, fallback); message.getHeaders().setContentType(result); } return result; }
@Override public Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType actualType, ResolvableType elementType, @Nullable MediaType mediaType, ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> hints) { Map<String, Object> allHints = Hints.merge(hints, getWriteHints(actualType, elementType, mediaType, request, response)); return write(inputStream, elementType, mediaType, response, allHints); }