/** * Read the given {@code Resource} into a {@code Flux} of {@code DataBuffer}s. * <p>If the resource is a file, it is read into an * {@code AsynchronousFileChannel} and turned to {@code Flux} via * {@link #readAsynchronousFileChannel(Callable, DataBufferFactory, int)} or else * fall back to {@link #readByteChannel(Callable, DataBufferFactory, int)}. * Closes the channel when the flux is terminated. * @param resource the resource to read from * @param dataBufferFactory the factory to create data buffers with * @param bufferSize the maximum size of the data buffers * @return a flux of data buffers read from the given channel */ public static Flux<DataBuffer> read( Resource resource, DataBufferFactory dataBufferFactory, int bufferSize) { return read(resource, 0, dataBufferFactory, bufferSize); }
/** * Read the given {@code Resource} into a {@code Flux} of {@code DataBuffer}s. * <p>If the resource is a file, it is read into an * {@code AsynchronousFileChannel} and turned to {@code Flux} via * {@link #readAsynchronousFileChannel(Callable, DataBufferFactory, int)} or else * fall back to {@link #readByteChannel(Callable, DataBufferFactory, int)}. * Closes the channel when the flux is terminated. * @param resource the resource to read from * @param dataBufferFactory the factory to create data buffers with * @param bufferSize the maximum size of the data buffers * @return a flux of data buffers read from the given channel */ public static Flux<DataBuffer> read( Resource resource, DataBufferFactory dataBufferFactory, int bufferSize) { return read(resource, 0, dataBufferFactory, bufferSize); }
@Override protected Flux<DataBuffer> encode(Resource resource, DataBufferFactory dataBufferFactory, ResolvableType type, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { if (logger.isDebugEnabled() && !Hints.isLoggingSuppressed(hints)) { String logPrefix = Hints.getLogPrefix(hints); logger.debug(logPrefix + "Writing [" + resource + "]"); } return DataBufferUtils.read(resource, dataBufferFactory, this.bufferSize); }
@Override protected Flux<DataBuffer> encode(Resource resource, DataBufferFactory dataBufferFactory, ResolvableType type, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { if (logger.isDebugEnabled() && !Hints.isLoggingSuppressed(hints)) { String logPrefix = Hints.getLogPrefix(hints); logger.debug(logPrefix + "Writing [" + resource + "]"); } return DataBufferUtils.read(resource, dataBufferFactory, this.bufferSize); }
private Flux<DataBuffer> writeResourceRegion( ResourceRegion region, DataBufferFactory bufferFactory, @Nullable Map<String, Object> hints) { Resource resource = region.getResource(); long position = region.getPosition(); long count = region.getCount(); if (logger.isDebugEnabled() && !Hints.isLoggingSuppressed(hints)) { logger.debug(Hints.getLogPrefix(hints) + "Writing region " + position + "-" + (position + count) + " of [" + resource + "]"); } Flux<DataBuffer> in = DataBufferUtils.read(resource, position, bufferFactory, this.bufferSize); return DataBufferUtils.takeUntilByteCount(in, count); }
@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); }); }); }
@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<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); }); }
private Flux<DataBuffer> writeResourceRegion( ResourceRegion region, DataBufferFactory bufferFactory, @Nullable Map<String, Object> hints) { Resource resource = region.getResource(); long position = region.getPosition(); long count = region.getCount(); if (logger.isDebugEnabled() && !Hints.isLoggingSuppressed(hints)) { logger.debug(Hints.getLogPrefix(hints) + "Writing region " + position + "-" + (position + count) + " of [" + resource + "]"); } Flux<DataBuffer> in = DataBufferUtils.read(resource, position, bufferFactory, this.bufferSize); return DataBufferUtils.takeUntilByteCount(in, count); }
@Test public void readResource() throws Exception { Flux<DataBuffer> flux = DataBufferUtils.read(this.resource, this.bufferFactory, 3); verifyReadData(flux); }
@Test public void readResourcePositionAndTakeUntil() throws Exception { Resource resource = new ClassPathResource("DataBufferUtilsTests.txt", getClass()); Flux<DataBuffer> flux = DataBufferUtils.read(resource, 3, this.bufferFactory, 3); flux = DataBufferUtils.takeUntilByteCount(flux, 5); StepVerifier.create(flux) .consumeNextWith(stringConsumer("bar")) .consumeNextWith(stringConsumer("ba")) .expectComplete() .verify(Duration.ofSeconds(5)); }
@Test public void readResourcePosition() throws Exception { Flux<DataBuffer> flux = DataBufferUtils.read(this.resource, 9, this.bufferFactory, 3); StepVerifier.create(flux) .consumeNextWith(stringConsumer("qux")) .expectComplete() .verify(Duration.ofSeconds(5)); }
@Test // SPR-16246 public void shouldSendLargeTextFile() throws IOException { prepareResponse(response -> {}); Resource resource = new ClassPathResource("largeTextFile.txt", getClass()); byte[] expected = Files.readAllBytes(resource.getFile().toPath()); Flux<DataBuffer> body = DataBufferUtils.read(resource, new DefaultDataBufferFactory(), 4096); this.webClient.post() .uri("/") .body(body, DataBuffer.class) .retrieve() .bodyToMono(Void.class) .block(Duration.ofSeconds(5)); expectRequest(request -> { ByteArrayOutputStream actual = new ByteArrayOutputStream(); try { request.getBody().copyTo(actual); } catch (IOException ex) { throw new IllegalStateException(ex); } assertEquals(expected.length, actual.size()); assertEquals(hash(expected), hash(actual.toByteArray())); }); }
@Test public void readByteArrayResourcePositionAndTakeUntil() throws Exception { Resource resource = new ByteArrayResource("foobarbazqux" .getBytes()); Flux<DataBuffer> flux = DataBufferUtils.read(resource, 3, this.bufferFactory, 3); flux = DataBufferUtils.takeUntilByteCount(flux, 5); StepVerifier.create(flux) .consumeNextWith(stringConsumer("bar")) .consumeNextWith(stringConsumer("ba")) .expectComplete() .verify(Duration.ofSeconds(5)); }
@Test // SPR-16376 public void customContentDisposition() throws IOException { Resource logo = new ClassPathResource("/org/springframework/http/converter/logo.jpg"); Flux<DataBuffer> buffers = DataBufferUtils.read(logo, new DefaultDataBufferFactory(), 1024); long contentLength = logo.contentLength(); MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder(); bodyBuilder.part("resource", logo) .headers(h -> h.setContentDispositionFormData("resource", "spring.jpg")); bodyBuilder.asyncPart("buffers", buffers, DataBuffer.class) .headers(h -> { h.setContentDispositionFormData("buffers", "buffers.jpg"); h.setContentType(MediaType.IMAGE_JPEG); h.setContentLength(contentLength); }); MultiValueMap<String, HttpEntity<?>> multipartData = bodyBuilder.build(); Map<String, Object> hints = Collections.emptyMap(); this.writer.write(Mono.just(multipartData), null, MediaType.MULTIPART_FORM_DATA, this.response, hints).block(); MultiValueMap<String, Part> requestParts = parse(hints); assertEquals(2, requestParts.size()); Part part = requestParts.getFirst("resource"); assertTrue(part instanceof FilePart); assertEquals("spring.jpg", ((FilePart) part).filename()); assertEquals(logo.getFile().length(), part.headers().getContentLength()); part = requestParts.getFirst("buffers"); assertTrue(part instanceof FilePart); assertEquals("buffers.jpg", ((FilePart) part).filename()); assertEquals(logo.getFile().length(), part.headers().getContentLength()); }
/** * Read the given {@code Resource} into a {@code Flux} of {@code DataBuffer}s. * <p>If the resource is a file, it is read into an * {@code AsynchronousFileChannel} and turned to {@code Flux} via * {@link #readAsynchronousFileChannel(Callable, DataBufferFactory, int)} or else * fall back to {@link #readByteChannel(Callable, DataBufferFactory, int)}. * Closes the channel when the flux is terminated. * @param resource the resource to read from * @param dataBufferFactory the factory to create data buffers with * @param bufferSize the maximum size of the data buffers * @return a flux of data buffers read from the given channel */ public static Flux<DataBuffer> read( Resource resource, DataBufferFactory dataBufferFactory, int bufferSize) { return read(resource, 0, dataBufferFactory, bufferSize); }
@Override protected Flux<DataBuffer> encode(Resource resource, DataBufferFactory dataBufferFactory, ResolvableType type, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { if (logger.isDebugEnabled() && !Hints.isLoggingSuppressed(hints)) { String logPrefix = Hints.getLogPrefix(hints); logger.debug(logPrefix + "Writing [" + resource + "]"); } return DataBufferUtils.read(resource, dataBufferFactory, this.bufferSize); }
@Override protected Flux<DataBuffer> encode(Resource resource, DataBufferFactory dataBufferFactory, ResolvableType type, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { if (logger.isDebugEnabled() && !Hints.isLoggingSuppressed(hints)) { String logPrefix = Hints.getLogPrefix(hints); logger.debug(logPrefix + "Writing [" + resource + "]"); } return DataBufferUtils.read(resource, dataBufferFactory, this.bufferSize); }
private Flux<DataBuffer> writeResourceRegion( ResourceRegion region, DataBufferFactory bufferFactory, @Nullable Map<String, Object> hints) { Resource resource = region.getResource(); long position = region.getPosition(); long count = region.getCount(); if (logger.isDebugEnabled() && !Hints.isLoggingSuppressed(hints)) { logger.debug(Hints.getLogPrefix(hints) + "Writing region " + position + "-" + (position + count) + " of [" + resource + "]"); } Flux<DataBuffer> in = DataBufferUtils.read(resource, position, bufferFactory, this.bufferSize); return DataBufferUtils.takeUntilByteCount(in, count); }
private Flux<DataBuffer> writeResourceRegion( ResourceRegion region, DataBufferFactory bufferFactory, @Nullable Map<String, Object> hints) { Resource resource = region.getResource(); long position = region.getPosition(); long count = region.getCount(); if (logger.isDebugEnabled() && !Hints.isLoggingSuppressed(hints)) { logger.debug(Hints.getLogPrefix(hints) + "Writing region " + position + "-" + (position + count) + " of [" + resource + "]"); } Flux<DataBuffer> in = DataBufferUtils.read(resource, position, bufferFactory, this.bufferSize); return DataBufferUtils.takeUntilByteCount(in, count); }