/** * Server-side only alternative to * {@link #write(Publisher, ResolvableType, MediaType, ReactiveHttpOutputMessage, Map)} * with additional context available. * @param actualType the actual return type of the method that returned the * value; for annotated controllers, the {@link MethodParameter} can be * accessed via {@link ResolvableType#getSource()}. * @param elementType the type of Objects in the input stream * @param mediaType the content type to use, possibly {@code null} indicating * the default content type of the writer should be used. * @param request the current request * @param response the current response * @return a {@link Mono} that indicates completion of writing or error */ default Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType actualType, ResolvableType elementType, @Nullable MediaType mediaType, ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> hints) { return write(inputStream, elementType, mediaType, response, hints); }
@Override public Mono<Void> insert(ClientHttpRequest outputMessage, Context context) { HttpMessageWriter<MultiValueMap<String, String>> messageWriter = findWriter(context, FORM_DATA_TYPE, MediaType.APPLICATION_FORM_URLENCODED); return messageWriter.write(Mono.just(this.data), FORM_DATA_TYPE, MediaType.APPLICATION_FORM_URLENCODED, outputMessage, context.hints()); } }
private static <T> Mono<Void> write(Publisher<? extends T> input, ResolvableType type, @Nullable MediaType mediaType, ReactiveHttpOutputMessage message, BodyInserter.Context context, HttpMessageWriter<T> writer) { return context.serverRequest() .map(request -> { ServerHttpResponse response = (ServerHttpResponse) message; return writer.write(input, type, type, mediaType, request, response, context.hints()); }) .orElseGet(() -> writer.write(input, type, mediaType, message, context.hints())); }
/** * Server-side only alternative to * {@link #write(Publisher, ResolvableType, MediaType, ReactiveHttpOutputMessage, Map)} * with additional context available. * @param actualType the actual return type of the method that returned the * value; for annotated controllers, the {@link MethodParameter} can be * accessed via {@link ResolvableType#getSource()}. * @param elementType the type of Objects in the input stream * @param mediaType the content type to use, possibly {@code null} indicating * the default content type of the writer should be used. * @param request the current request * @param response the current response * @return a {@link Mono} that indicates completion of writing or error */ default Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType actualType, ResolvableType elementType, @Nullable MediaType mediaType, ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> hints) { return write(inputStream, elementType, mediaType, response, hints); }
@Override public Mono<Void> insert(ClientHttpRequest outputMessage, Context context) { HttpMessageWriter<MultiValueMap<String, HttpEntity<?>>> messageWriter = findWriter(context, MULTIPART_DATA_TYPE, MediaType.MULTIPART_FORM_DATA); MultiValueMap<String, HttpEntity<?>> body = this.builder.build(); return messageWriter.write(Mono.just(body), MULTIPART_DATA_TYPE, MediaType.MULTIPART_FORM_DATA, outputMessage, context.hints()); } }
@Override public Mono<Void> write(Publisher<? extends MultiValueMap<String, ?>> inputStream, ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage outputMessage, Map<String, Object> hints) { return Mono.from(inputStream).flatMap(map -> { if (this.formWriter == null || isMultipart(map, mediaType)) { return writeMultipart(map, outputMessage, hints); } else { @SuppressWarnings("unchecked") MultiValueMap<String, String> formData = (MultiValueMap<String, String>) map; return this.formWriter.write(Mono.just(formData), elementType, mediaType, outputMessage, hints); } }); }
@SuppressWarnings("unchecked") private <T> Mono<Void> write(T value, @Nullable MediaType contentType, ServerWebExchange exchange) { Publisher<T> input = Mono.justOrEmpty(value); ResolvableType elementType = ResolvableType.forClass(value.getClass()); return ((HttpMessageWriter<T>) this.writer).write( input, elementType, contentType, exchange.getResponse(), Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix())); }
@Override public Mono<Void> write(Publisher<? extends MultiValueMap<String, ?>> inputStream, ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage outputMessage, Map<String, Object> hints) { return Mono.from(inputStream).flatMap(map -> { if (this.formWriter == null || isMultipart(map, mediaType)) { return writeMultipart(map, outputMessage, hints); } else { @SuppressWarnings("unchecked") MultiValueMap<String, String> formData = (MultiValueMap<String, String>) map; return this.formWriter.write(Mono.just(formData), elementType, mediaType, outputMessage, hints); } }); }
private void testDefaultMediaType(MediaType negotiatedMediaType) { this.mediaTypeCaptor = ArgumentCaptor.forClass(MediaType.class); MimeType defaultContentType = MimeTypeUtils.TEXT_XML; HttpMessageWriter<String> writer = getWriter(defaultContentType); writer.write(Mono.just("body"), forClass(String.class), negotiatedMediaType, this.response, NO_HINTS); assertEquals(defaultContentType, this.response.getHeaders().getContentType()); assertEquals(defaultContentType, this.mediaTypeCaptor.getValue()); }
.write(bodyPublisher, resolvableType, contentType, outputMessage, DEFAULT_HINTS);
@Test public void useNegotiatedMediaType() { HttpMessageWriter<String> writer = getWriter(MimeTypeUtils.ALL); writer.write(Mono.just("body"), forClass(String.class), TEXT_PLAIN, this.response, NO_HINTS); assertEquals(TEXT_PLAIN, response.getHeaders().getContentType()); assertEquals(TEXT_PLAIN, this.mediaTypeCaptor.getValue()); }
@Test public void useHttpOutputMessageMediaType() { MediaType outputMessageMediaType = MediaType.TEXT_HTML; this.response.getHeaders().setContentType(outputMessageMediaType); HttpMessageWriter<String> writer = getWriter(TEXT_PLAIN_UTF_8, TEXT_HTML); writer.write(Mono.just("body"), forClass(String.class), TEXT_PLAIN, this.response, NO_HINTS); assertEquals(outputMessageMediaType, this.response.getHeaders().getContentType()); assertEquals(outputMessageMediaType, this.mediaTypeCaptor.getValue()); }
@Test public void setContentLengthForMonoBody() { DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); DataBuffer buffer = factory.wrap("body".getBytes(StandardCharsets.UTF_8)); HttpMessageWriter<String> writer = getWriter(Flux.just(buffer), MimeTypeUtils.TEXT_PLAIN); writer.write(Mono.just("body"), forClass(String.class), TEXT_PLAIN, this.response, NO_HINTS).block(); assertEquals(4, this.response.getHeaders().getContentLength()); }
@Test public void useNegotiatedMediaTypeCharset() { MediaType negotiatedMediaType = new MediaType("text", "html", ISO_8859_1); HttpMessageWriter<String> writer = getWriter(TEXT_PLAIN_UTF_8, TEXT_HTML); writer.write(Mono.just("body"), forClass(String.class), negotiatedMediaType, this.response, NO_HINTS); assertEquals(negotiatedMediaType, this.response.getHeaders().getContentType()); assertEquals(negotiatedMediaType, this.mediaTypeCaptor.getValue()); }
@Test // SPR-17220 public void emptyBodyWritten() { HttpMessageWriter<String> writer = getWriter(MimeTypeUtils.TEXT_PLAIN); writer.write(Mono.empty(), forClass(String.class), TEXT_PLAIN, this.response, NO_HINTS).block(); StepVerifier.create(this.response.getBody()).expectComplete(); assertEquals(0, this.response.getHeaders().getContentLength()); }
@Test public void useDefaultMediaTypeCharset() { HttpMessageWriter<String> writer = getWriter(TEXT_PLAIN_UTF_8, TEXT_HTML); writer.write(Mono.just("body"), forClass(String.class), TEXT_HTML, response, NO_HINTS); assertEquals(new MediaType("text", "html", UTF_8), this.response.getHeaders().getContentType()); assertEquals(new MediaType("text", "html", UTF_8), this.mediaTypeCaptor.getValue()); }
.write(bodyPublisher, resolvableType, contentType, outputMessage, DEFAULT_HINTS);
return writer.write((Publisher) publisher, actualType, elementType, bestMediaType, request, response, Hints.from(Hints.LOG_PREFIX_HINT, logPrefix));
for (HttpMessageWriter<?> writer : this.codecConfigurer.getWriters()) { if (writer.canWrite(bodyType, bestMediaType)) { return ((HttpMessageWriter<Object>) writer).write(publisher, elementType, bestMediaType, exchange.getResponse(), Collections.emptyMap());