/** * Extractor that returns the raw {@link DataBuffer DataBuffers}. * <p><strong>Note:</strong> the data buffers should be * {@link org.springframework.core.io.buffer.DataBufferUtils#release(DataBuffer) * released} after being used. * @return {@code BodyExtractor} for data buffers */ public static BodyExtractor<Flux<DataBuffer>, ReactiveHttpInputMessage> toDataBuffers() { return (inputMessage, context) -> inputMessage.getBody(); }
@Override public Flux<T> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { MediaType contentType = getContentType(message); return this.decoder.decode(message.getBody(), elementType, contentType, hints); }
@Override public Mono<T> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { MediaType contentType = getContentType(message); return this.decoder.decodeToMono(message.getBody(), elementType, contentType, hints); }
private static Mono<Void> consumeAndCancel(ReactiveHttpInputMessage message) { return message.getBody() .map(buffer -> { DataBufferUtils.release(buffer); throw new ReadCancellationException(); }) .onErrorResume(ReadCancellationException.class, ex -> Mono.empty()) .then(); }
@Override public Mono<Object> readMono( ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { // We're ahead of String + "*/*" // Let's see if we can aggregate the output (lest we time out)... if (elementType.resolve() == String.class) { Flux<DataBuffer> body = message.getBody(); return stringDecoder.decodeToMono(body, elementType, null, null).cast(Object.class); } return Mono.error(new UnsupportedOperationException( "ServerSentEventHttpMessageReader only supports reading stream of events as a Flux")); }
@Override public Flux<T> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { MediaType contentType = getContentType(message); return this.decoder.decode(message.getBody(), elementType, contentType, hints); }
@Override public Mono<T> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { MediaType contentType = getContentType(message); return this.decoder.decodeToMono(message.getBody(), elementType, contentType, hints); }
@Override public Mono<MultiValueMap<String, String>> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { MediaType contentType = message.getHeaders().getContentType(); Charset charset = getMediaTypeCharset(contentType); return DataBufferUtils.join(message.getBody()) .map(buffer -> { CharBuffer charBuffer = charset.decode(buffer.asByteBuffer()); String body = charBuffer.toString(); DataBufferUtils.release(buffer); MultiValueMap<String, String> formData = parseFormData(charset, body); logFormData(formData, hints); return formData; }); }
@Override public Flux<Object> read( ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { boolean shouldWrap = isServerSentEvent(elementType); ResolvableType valueType = (shouldWrap ? elementType.getGeneric() : elementType); return stringDecoder.decode(message.getBody(), STRING_TYPE, null, hints) .bufferUntil(line -> line.equals("")) .concatMap(lines -> buildEvent(lines, valueType, shouldWrap, hints)); }
@Override public Mono<Object> readMono( ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { // We're ahead of String + "*/*" // Let's see if we can aggregate the output (lest we time out)... if (elementType.resolve() == String.class) { Flux<DataBuffer> body = message.getBody(); return stringDecoder.decodeToMono(body, elementType, null, null).cast(Object.class); } return Mono.error(new UnsupportedOperationException( "ServerSentEventHttpMessageReader only supports reading stream of events as a Flux")); }
private static <T> Flux<T> unsupportedErrorHandler( ReactiveHttpInputMessage message, UnsupportedMediaTypeException ex) { Flux<T> result; if (message.getHeaders().getContentType() == null) { // Maybe it's okay there is no content type, if there is no content.. result = message.getBody().map(buffer -> { DataBufferUtils.release(buffer); throw ex; }); } else { result = message instanceof ClientHttpResponse ? consumeAndCancel(message).thenMany(Flux.error(ex)) : Flux.error(ex); } return result; }
@Override public Mono<MultiValueMap<String, String>> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { MediaType contentType = message.getHeaders().getContentType(); Charset charset = getMediaTypeCharset(contentType); return DataBufferUtils.join(message.getBody()) .map(buffer -> { CharBuffer charBuffer = charset.decode(buffer.asByteBuffer()); String body = charBuffer.toString(); DataBufferUtils.release(buffer); MultiValueMap<String, String> formData = parseFormData(charset, body); logFormData(formData, hints); return formData; }); }
@Override public Flux<Object> read( ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { boolean shouldWrap = isServerSentEvent(elementType); ResolvableType valueType = (shouldWrap ? elementType.getGeneric() : elementType); return stringDecoder.decode(message.getBody(), STRING_TYPE, null, hints) .bufferUntil(line -> line.equals("")) .concatMap(lines -> buildEvent(lines, valueType, shouldWrap, hints)); }
.forNIO(listener); this.inputMessage.getBody().subscribe(buffer -> { byte[] resultBytes = new byte[buffer.readableByteCount()]; buffer.read(resultBytes);
.forNIO(listener); this.inputMessage.getBody().subscribe(buffer -> { byte[] resultBytes = new byte[buffer.readableByteCount()]; buffer.read(resultBytes);
/** * Return a {@code BodyExtractor} that returns the body of the message as a {@link Flux} of * {@link DataBuffer}s. * <p><strong>Note</strong> that the returned buffers should be released after usage by calling * {@link org.springframework.core.io.buffer.DataBufferUtils#release(DataBuffer)} * @return a {@code BodyExtractor} that returns the body * @see ReactiveHttpInputMessage#getBody() */ public static BodyExtractor<Flux<DataBuffer>, ReactiveHttpInputMessage> toDataBuffers() { return (inputMessage, context) -> inputMessage.getBody(); }
@Override public Flux<T> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { MediaType contentType = getContentType(message); return this.decoder.decode(message.getBody(), elementType, contentType, hints); }
@Override public Mono<Object> readMono( ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { // We're ahead of String + "*/*" // Let's see if we can aggregate the output (lest we time out)... if (elementType.resolve() == String.class) { Flux<DataBuffer> body = message.getBody(); return stringDecoder.decodeToMono(body, elementType, null, null).cast(Object.class); } return Mono.error(new UnsupportedOperationException( "ServerSentEventHttpMessageReader only supports reading stream of events as a Flux")); }
@Override public Flux<Object> read( ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { boolean shouldWrap = isServerSentEvent(elementType); ResolvableType valueType = (shouldWrap ? elementType.getGeneric() : elementType); return stringDecoder.decode(message.getBody(), STRING_TYPE, null, hints) .bufferUntil(line -> line.equals("")) .concatMap(lines -> buildEvent(lines, valueType, shouldWrap, hints)); }
@Override public Flux<Object> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { boolean shouldWrap = isServerSentEvent(elementType); ResolvableType valueType = (shouldWrap ? elementType.getGeneric() : elementType); return stringDecoder.decode(message.getBody(), STRING_TYPE, null, Collections.emptyMap()) .bufferUntil(line -> line.equals("")) .concatMap(lines -> buildEvent(lines, valueType, shouldWrap, hints)); }