List of usage examples for org.springframework.http HttpRange toResourceRegions
public static List<ResourceRegion> toResourceRegions(List<HttpRange> ranges, Resource resource)
From source file:org.springframework.http.codec.ResourceHttpMessageWriter.java
@Override @SuppressWarnings("unchecked") public Mono<Void> write(Publisher<? extends Resource> inputStream, @Nullable ResolvableType actualType, ResolvableType elementType, @Nullable MediaType mediaType, ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> hints) { HttpHeaders headers = response.getHeaders(); headers.set(HttpHeaders.ACCEPT_RANGES, "bytes"); List<HttpRange> ranges; try {// w w w . j a va 2 s . c o m ranges = request.getHeaders().getRange(); } catch (IllegalArgumentException ex) { response.setStatusCode(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE); return response.setComplete(); } return Mono.from(inputStream).flatMap(resource -> { if (ranges.isEmpty()) { return writeResource(resource, elementType, mediaType, response, hints); } response.setStatusCode(HttpStatus.PARTIAL_CONTENT); List<ResourceRegion> regions = HttpRange.toResourceRegions(ranges, resource); MediaType resourceMediaType = getResourceMediaType(mediaType, resource, hints); if (regions.size() == 1) { ResourceRegion region = regions.get(0); headers.setContentType(resourceMediaType); long contentLength = lengthOf(resource); if (contentLength != -1) { long start = region.getPosition(); long end = start + region.getCount() - 1; end = Math.min(end, contentLength - 1); headers.add("Content-Range", "bytes " + start + '-' + end + '/' + contentLength); headers.setContentLength(end - start + 1); } return writeSingleRegion(region, response, hints); } else { String boundary = MimeTypeUtils.generateMultipartBoundaryString(); MediaType multipartType = MediaType.parseMediaType("multipart/byteranges;boundary=" + boundary); headers.setContentType(multipartType); Map<String, Object> allHints = Hints.merge(hints, ResourceRegionEncoder.BOUNDARY_STRING_HINT, boundary); return encodeAndWriteRegions(Flux.fromIterable(regions), resourceMediaType, response, allHints); } }); }
From source file:org.springframework.web.servlet.resource.ResourceHttpRequestHandler.java
/** * Processes a resource request./*from ww w . jav a 2 s . c o m*/ * <p>Checks for the existence of the requested resource in the configured list of locations. * If the resource does not exist, a {@code 404} response will be returned to the client. * If the resource exists, the request will be checked for the presence of the * {@code Last-Modified} header, and its value will be compared against the last-modified * timestamp of the given resource, returning a {@code 304} status code if the * {@code Last-Modified} value is greater. If the resource is newer than the * {@code Last-Modified} value, or the header is not present, the content resource * of the resource will be written to the response with caching headers * set to expire one year in the future. */ @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // For very general mappings (e.g. "/") we need to check 404 first Resource resource = getResource(request); if (resource == null) { logger.trace("No matching resource found - returning 404"); response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } if (HttpMethod.OPTIONS.matches(request.getMethod())) { response.setHeader("Allow", getAllowHeader()); return; } // Supported methods and required session checkRequest(request); // Header phase if (new ServletWebRequest(request, response).checkNotModified(resource.lastModified())) { logger.trace("Resource not modified - returning 304"); return; } // Apply cache settings, if any prepareResponse(response); // Check the media type for the resource MediaType mediaType = getMediaType(request, resource); if (mediaType != null) { if (logger.isTraceEnabled()) { logger.trace("Determined media type '" + mediaType + "' for " + resource); } } else { if (logger.isTraceEnabled()) { logger.trace("No media type found for " + resource + " - not sending a content-type header"); } } // Content phase if (METHOD_HEAD.equals(request.getMethod())) { setHeaders(response, resource, mediaType); logger.trace("HEAD request - skipping content"); return; } ServletServerHttpResponse outputMessage = new ServletServerHttpResponse(response); if (request.getHeader(HttpHeaders.RANGE) == null) { Assert.state(this.resourceHttpMessageConverter != null, "Not initialized"); setHeaders(response, resource, mediaType); this.resourceHttpMessageConverter.write(resource, mediaType, outputMessage); } else { Assert.state(this.resourceRegionHttpMessageConverter != null, "Not initialized"); response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes"); ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(request); try { List<HttpRange> httpRanges = inputMessage.getHeaders().getRange(); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); this.resourceRegionHttpMessageConverter.write(HttpRange.toResourceRegions(httpRanges, resource), mediaType, outputMessage); } catch (IllegalArgumentException ex) { response.setHeader("Content-Range", "bytes */" + resource.contentLength()); response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); } } }