@Override public Mono<T> decodeToMono(Publisher<DataBuffer> inputStream, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { return DataBufferUtils.join(inputStream) .map(buffer -> decodeDataBuffer(buffer, elementType, mimeType, hints)); }
@Override public Mono<T> decodeToMono(Publisher<DataBuffer> inputStream, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { return DataBufferUtils.join(inputStream) .map(buffer -> decodeDataBuffer(buffer, elementType, mimeType, hints)); }
@SuppressWarnings("deprecation") @Override public Mono<Resource> transform(ServerWebExchange exchange, Resource inputResource, ResourceTransformerChain transformerChain) { return transformerChain.transform(exchange, inputResource) .flatMap(outputResource -> { String filename = outputResource.getFilename(); if (!"css".equals(StringUtils.getFilenameExtension(filename)) || inputResource instanceof EncodedResourceResolver.EncodedResource || inputResource instanceof GzipResourceResolver.GzippedResource) { return Mono.just(outputResource); } DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory(); Flux<DataBuffer> flux = DataBufferUtils .read(outputResource, bufferFactory, StreamUtils.BUFFER_SIZE); return DataBufferUtils.join(flux) .flatMap(dataBuffer -> { CharBuffer charBuffer = DEFAULT_CHARSET.decode(dataBuffer.asByteBuffer()); DataBufferUtils.release(dataBuffer); String cssContent = charBuffer.toString(); return transformContent(cssContent, outputResource, transformerChain, exchange); }); }); }
@Override public Mono<Resource> transform(ServerWebExchange exchange, Resource inputResource, ResourceTransformerChain chain) { return chain.transform(exchange, inputResource) .flatMap(outputResource -> { String name = outputResource.getFilename(); if (!this.fileExtension.equals(StringUtils.getFilenameExtension(name))) { return Mono.just(outputResource); } DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory(); Flux<DataBuffer> flux = DataBufferUtils .read(outputResource, bufferFactory, StreamUtils.BUFFER_SIZE); return DataBufferUtils.join(flux) .flatMap(dataBuffer -> { CharBuffer charBuffer = DEFAULT_CHARSET.decode(dataBuffer.asByteBuffer()); DataBufferUtils.release(dataBuffer); String content = charBuffer.toString(); return transform(content, outputResource, chain, exchange); }); }); }
@Override public Mono<String> getResourceVersion(Resource resource) { Flux<DataBuffer> flux = DataBufferUtils.read(resource, dataBufferFactory, StreamUtils.BUFFER_SIZE); return DataBufferUtils.join(flux) .map(buffer -> { byte[] result = new byte[buffer.readableByteCount()]; buffer.read(result); DataBufferUtils.release(buffer); return DigestUtils.md5DigestAsHex(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; }); }
private String partToUtf8String(Part part) { DataBuffer buffer = DataBufferUtils.join(part.content()).block(); return DataBufferTestUtils.dumpString(buffer, StandardCharsets.UTF_8); }
@Override public Mono<Message> decodeToMono(Publisher<DataBuffer> inputStream, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { return DataBufferUtils.join(inputStream).map(dataBuffer -> { try { Message.Builder builder = getMessageBuilder(elementType.toClass()); ByteBuffer buffer = dataBuffer.asByteBuffer(); builder.mergeFrom(CodedInputStream.newInstance(buffer), this.extensionRegistry); return builder.build(); } catch (IOException ex) { throw new DecodingException("I/O error while parsing input stream", ex); } catch (Exception ex) { throw new DecodingException("Could not read Protobuf message: " + ex.getMessage(), ex); } finally { DataBufferUtils.release(dataBuffer); } } ); }
@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 @SuppressWarnings({"rawtypes", "unchecked"}) // on JDK 9 where XMLEventReader is Iterator<Object> public Flux<XMLEvent> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { Flux<DataBuffer> flux = Flux.from(inputStream); if (this.useAalto) { AaltoDataBufferToXmlEvent aaltoMapper = new AaltoDataBufferToXmlEvent(); return flux.flatMap(aaltoMapper) .doFinally(signalType -> aaltoMapper.endOfInput()); } else { Mono<DataBuffer> singleBuffer = DataBufferUtils.join(flux); return singleBuffer. flatMapMany(dataBuffer -> { try { InputStream is = dataBuffer.asInputStream(); Iterator eventReader = inputFactory.createXMLEventReader(is); return Flux.fromIterable((Iterable<XMLEvent>) () -> eventReader) .doFinally(t -> DataBufferUtils.release(dataBuffer)); } catch (XMLStreamException ex) { return Mono.error(ex); } }); } }
@Override public Mono<Message> decodeToMono(Publisher<DataBuffer> inputStream, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { return DataBufferUtils.join(inputStream).map(dataBuffer -> { try { Message.Builder builder = getMessageBuilder(elementType.toClass()); ByteBuffer buffer = dataBuffer.asByteBuffer(); builder.mergeFrom(CodedInputStream.newInstance(buffer), this.extensionRegistry); return builder.build(); } catch (IOException ex) { throw new DecodingException("I/O error while parsing input stream", ex); } catch (Exception ex) { throw new DecodingException("Could not read Protobuf message: " + ex.getMessage(), ex); } finally { DataBufferUtils.release(dataBuffer); } } ); }
private static Mono<WebClientResponseException> createResponseException( ClientResponse response, HttpRequest request) { return DataBufferUtils.join(response.body(BodyExtractors.toDataBuffers())) .map(dataBuffer -> { byte[] bytes = new byte[dataBuffer.readableByteCount()];
@Override @SuppressWarnings({"rawtypes", "unchecked"}) // on JDK 9 where XMLEventReader is Iterator<Object> public Flux<XMLEvent> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { Flux<DataBuffer> flux = Flux.from(inputStream); if (this.useAalto) { AaltoDataBufferToXmlEvent aaltoMapper = new AaltoDataBufferToXmlEvent(); return flux.flatMap(aaltoMapper) .doFinally(signalType -> aaltoMapper.endOfInput()); } else { Mono<DataBuffer> singleBuffer = DataBufferUtils.join(flux); return singleBuffer. flatMapMany(dataBuffer -> { try { InputStream is = dataBuffer.asInputStream(); Iterator eventReader = inputFactory.createXMLEventReader(is); return Flux.fromIterable((Iterable<XMLEvent>) () -> eventReader) .doFinally(t -> DataBufferUtils.release(dataBuffer)); } catch (XMLStreamException ex) { return Mono.error(ex); } }); } }
@Test public void joinErrors() { DataBuffer foo = stringBuffer("foo"); DataBuffer bar = stringBuffer("bar"); Flux<DataBuffer> flux = Flux.just(foo, bar).concatWith(Flux.error(new RuntimeException())); Mono<DataBuffer> result = DataBufferUtils.join(flux); StepVerifier.create(result) .expectError(RuntimeException.class) .verify(); }
@Test public void part() { MethodParameter param = this.testMethod.annot(requestPart()).arg(Part.class); MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder(); bodyBuilder.part("name", new Person("Jones")); Part actual = resolveArgument(param, bodyBuilder); DataBuffer buffer = DataBufferUtils.join(actual.content()).block(); assertEquals("{\"name\":\"Jones\"}", DataBufferTestUtils.dumpString(buffer, StandardCharsets.UTF_8)); }
@Test public void joinCanceled() { Flux<DataBuffer> source = Flux.concat( deferStringBuffer("foo"), deferStringBuffer("bar"), deferStringBuffer("baz") ); Mono<DataBuffer> result = DataBufferUtils.join(source); StepVerifier.create(result) .thenCancel() .verify(); }
@Test // SPR-16350 public void fromMultipartDataWithMultipleValues() { MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); map.put("name", Arrays.asList("value1", "value2")); BodyInserters.FormInserter<Object> inserter = BodyInserters.fromMultipartData(map); MockClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, URI.create("http://example.com")); Mono<Void> result = inserter.insert(request, this.context); StepVerifier.create(result).expectComplete().verify(); StepVerifier.create(DataBufferUtils.join(request.getBody())) .consumeNextWith(dataBuffer -> { byte[] resultBytes = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(resultBytes); DataBufferUtils.release(dataBuffer); String content = new String(resultBytes, StandardCharsets.UTF_8); assertThat(content, containsString("Content-Disposition: form-data; name=\"name\"\r\n" + "Content-Type: text/plain;charset=UTF-8\r\n" + "Content-Length: 6\r\n" + "\r\n" + "value1")); assertThat(content, containsString("Content-Disposition: form-data; name=\"name\"\r\n" + "Content-Type: text/plain;charset=UTF-8\r\n" + "Content-Length: 6\r\n" + "\r\n" + "value2")); }) .expectComplete() .verify(); }
private void assertFooPart(Part part) { assertEquals("fooPart", part.name()); assertTrue(part instanceof FilePart); assertEquals("foo.txt", ((FilePart) part).filename()); StepVerifier.create(DataBufferUtils.join(part.content())) .consumeNextWith(buffer -> { assertEquals(12, buffer.readableByteCount()); byte[] byteContent = new byte[12]; buffer.read(byteContent); assertEquals("Lorem Ipsum.", new String(byteContent)); }) .verifyComplete(); }
@Test public void join() { DataBuffer foo = stringBuffer("foo"); DataBuffer bar = stringBuffer("bar"); DataBuffer baz = stringBuffer("baz"); Flux<DataBuffer> flux = Flux.just(foo, bar, baz); Mono<DataBuffer> result = DataBufferUtils.join(flux); StepVerifier.create(result) .consumeNextWith(dataBuffer -> { assertEquals("foobarbaz", DataBufferTestUtils.dumpString(dataBuffer, StandardCharsets.UTF_8)); release(dataBuffer); }) .verifyComplete(); }
@Test public void resolveParts() { ServerHttpRequest request = generateMultipartRequest(); ResolvableType elementType = forClassWithGenerics(MultiValueMap.class, String.class, Part.class); MultiValueMap<String, Part> parts = this.reader.readMono(elementType, request, emptyMap()).block(); assertEquals(2, parts.size()); assertTrue(parts.containsKey("fooPart")); Part part = parts.getFirst("fooPart"); assertTrue(part instanceof FilePart); assertEquals("fooPart", part.name()); assertEquals("foo.txt", ((FilePart) part).filename()); DataBuffer buffer = DataBufferUtils.join(part.content()).block(); assertEquals(12, buffer.readableByteCount()); byte[] byteContent = new byte[12]; buffer.read(byteContent); assertEquals("Lorem Ipsum.", new String(byteContent)); assertTrue(parts.containsKey("barPart")); part = parts.getFirst("barPart"); assertTrue(part instanceof FormFieldPart); assertEquals("barPart", part.name()); assertEquals("bar", ((FormFieldPart) part).value()); }