List of usage examples for org.springframework.core.io.buffer DataBufferUtils retain
@SuppressWarnings("unchecked") public static <T extends DataBuffer> T retain(T dataBuffer)
From source file:org.springframework.cloud.gateway.handler.predicate.ReadBodyPredicateFactory.java
@Override @SuppressWarnings("unchecked") public AsyncPredicate<ServerWebExchange> applyAsync(Config config) { return exchange -> { Class inClass = config.getInClass(); Object cachedBody = exchange.getAttribute(CACHE_REQUEST_BODY_OBJECT_KEY); Mono<?> modifiedBody;//from ww w. j ava 2 s .c o m // We can only read the body from the request once, once that happens if we // try to read the body again an exception will be thrown. The below if/else // caches the body object as a request attribute in the ServerWebExchange // so if this filter is run more than once (due to more than one route // using it) we do not try to read the request body multiple times if (cachedBody != null) { try { boolean test = config.predicate.test(cachedBody); exchange.getAttributes().put(TEST_ATTRIBUTE, test); return Mono.just(test); } catch (ClassCastException e) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Predicate test failed because class in predicate " + "does not match the cached body object", e); } } return Mono.just(false); } else { // Join all the DataBuffers so we have a single DataBuffer for the body return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> { // Update the retain counts so we can read the body twice, // once to parse into an object // that we can test the predicate against and a second time // when the HTTP client sends // the request downstream // Note: if we end up reading the body twice we will run into // a problem, but as of right // now there is no good use case for doing this DataBufferUtils.retain(dataBuffer); // Make a slice for each read so each read has its own // read/write indexes Flux<DataBuffer> cachedFlux = Flux .defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount()))); ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) { @Override public Flux<DataBuffer> getBody() { return cachedFlux; } }; return ServerRequest.create(exchange.mutate().request(mutatedRequest).build(), messageReaders) .bodyToMono(inClass).doOnNext(objectValue -> { exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, objectValue); exchange.getAttributes().put(CACHED_REQUEST_BODY_KEY, cachedFlux); }).map(objectValue -> config.predicate.test(objectValue)); }); } }; }
From source file:org.springframework.http.codec.multipart.DefaultMultipartMessageReader.java
/** * Convert the given data buffer into a Part. All data up until the header separator (\r\n\r\n) * is passed to {@link #toHeaders(DataBuffer)}, the remaining data is considered to be the * body./* w w w .j a v a 2 s .c o m*/ */ private static Part toPart(DataBuffer dataBuffer) { int readPosition = dataBuffer.readPosition(); if (dataBuffer.readableByteCount() >= 2) { if (dataBuffer.getByte(readPosition) == CR && dataBuffer.getByte(readPosition + 1) == LF) { dataBuffer.readPosition(readPosition + 2); } } if (logger.isTraceEnabled()) { logger.trace("Part data: " + toString(dataBuffer)); } int endIdx = HEADER_MATCHER.match(dataBuffer); HttpHeaders headers; DataBuffer body; if (endIdx > 0) { readPosition = dataBuffer.readPosition(); int headersLength = endIdx + 1 - (readPosition + HEADER_BODY_SEPARATOR.length); DataBuffer headersBuffer = dataBuffer.retainedSlice(readPosition, headersLength); int bodyLength = dataBuffer.writePosition() - (1 + endIdx); body = dataBuffer.retainedSlice(endIdx + 1, bodyLength); headers = toHeaders(headersBuffer); } else { headers = new HttpHeaders(); body = DataBufferUtils.retain(dataBuffer); } DataBufferUtils.release(dataBuffer); ContentDisposition cd = headers.getContentDisposition(); MediaType contentType = headers.getContentType(); if (StringUtils.hasLength(cd.getFilename())) { return new DefaultFilePart(headers, body); } else if (StringUtils.hasLength(cd.getName()) && (contentType == null || MediaType.TEXT_PLAIN.isCompatibleWith(contentType))) { return new DefaultFormPart(headers, body); } else { return new DefaultPart(headers, body); } }