/** * Constructor with a fully initialized {@link HttpMessageWriter}. */ public HttpMessageWriterView(HttpMessageWriter<?> writer) { Assert.notNull(writer, "HttpMessageWriter is required"); this.writer = writer; this.canWriteMap = writer.canWrite(ResolvableType.forClass(Map.class), null); }
private List<MediaType> getMediaTypesFor(ResolvableType elementType) { return getMessageWriters().stream() .filter(converter -> converter.canWrite(elementType, null)) .flatMap(converter -> converter.getWritableMediaTypes().stream()) .collect(Collectors.toList()); }
/** * 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); }
private static <T, P extends Publisher<?>, M extends ReactiveHttpOutputMessage> BodyInserter<T, M> bodyInserterFor(P body, ResolvableType bodyType) { return (m, context) -> { MediaType contentType = m.getHeaders().getContentType(); Supplier<Stream<HttpMessageWriter<?>>> messageWriters = context.messageWriters(); return messageWriters.get() .filter(messageWriter -> messageWriter.canWrite(bodyType, contentType)) .findFirst() .map(BodyInserters::cast) .map(messageWriter -> messageWriter .write(body, bodyType, contentType, m, context.hints())) .orElseGet(() -> { List<MediaType> supportedMediaTypes = messageWriters.get() .flatMap(reader -> reader.getWritableMediaTypes().stream()) .collect(Collectors.toList()); UnsupportedMediaTypeException error = new UnsupportedMediaTypeException(contentType, supportedMediaTypes); return Mono.error(error); }); }; }
/** * {@inheritDoc} * <p>The implementation of this method for {@link HttpMessageWriterView} * delegates to {@link HttpMessageWriter#getWritableMediaTypes()}. */ @Override public List<MediaType> getSupportedMediaTypes() { return this.writer.getWritableMediaTypes(); }
private static List<MediaType> initMediaTypes(@Nullable HttpMessageWriter<?> formWriter) { List<MediaType> result = new ArrayList<>(); result.add(MediaType.MULTIPART_FORM_DATA); if (formWriter != null) { result.addAll(formWriter.getWritableMediaTypes()); } return Collections.unmodifiableList(result); }
@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()); } }
@Override public void writer(HttpMessageWriter<?> writer) { boolean canWriteObject = writer.canWrite(ResolvableType.forClass(Object.class), null); (canWriteObject ? this.objectWriters : this.typedWriters).add(writer); }
private List<MediaType> getProducibleMediaTypes(ResolvableType elementType) { return this.codecConfigurer.getWriters() .stream() .filter(converter -> converter.canWrite(elementType, null)) .flatMap(converter -> converter.getWritableMediaTypes().stream()) .collect(Collectors.toList()); }
private static UnsupportedMediaTypeException unsupportedError(ResolvableType bodyType, BodyInserter.Context context, @Nullable MediaType mediaType) { List<MediaType> supportedMediaTypes = context.messageWriters().stream() .flatMap(reader -> reader.getWritableMediaTypes().stream()) .collect(Collectors.toList()); return new UnsupportedMediaTypeException(mediaType, supportedMediaTypes, bodyType); }
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())); }
private static <T> HttpMessageWriter<T> findWriter( BodyInserter.Context context, ResolvableType elementType, @Nullable MediaType mediaType) { return context.messageWriters().stream() .filter(messageWriter -> messageWriter.canWrite(elementType, mediaType)) .findFirst() .map(BodyInserters::<T>cast) .orElseThrow(() -> new IllegalStateException( "No HttpMessageWriter for \"" + mediaType + "\" and \"" + elementType + "\"")); }
private List<MediaType> getProducibleMediaTypes(ResolvableType elementType) { return getMessageWriters().stream() .filter(converter -> converter.canWrite(elementType, null)) .flatMap(converter -> converter.getWritableMediaTypes().stream()) .collect(Collectors.toList()); }
private static List<MediaType> initMediaTypes(@Nullable HttpMessageWriter<?> formWriter) { List<MediaType> result = new ArrayList<>(); result.add(MediaType.MULTIPART_FORM_DATA); if (formWriter != null) { result.addAll(formWriter.getWritableMediaTypes()); } return Collections.unmodifiableList(result); }
/** * 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); }