diff --git a/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java index be98db9122a1..39a74e8b5f2b 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java @@ -22,7 +22,11 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.springframework.core.io.Resource; import org.springframework.core.io.support.ResourceRegion; @@ -178,12 +182,28 @@ private void writeResourceRegionCollection(Collection resourceRe String boundaryString = MimeTypeUtils.generateMultipartBoundaryString(); responseHeaders.set(HttpHeaders.CONTENT_TYPE, "multipart/byteranges; boundary=" + boundaryString); OutputStream out = outputMessage.getBody(); + // Allows reuse of streams + Map cleanup = new HashMap<>(); + List exs = new ArrayList<>(); + + try { + for (ResourceRegion region : resourceRegions) { + long start = region.getPosition(); + long end = start + region.getCount() - 1; + + InputStream in = cleanup.computeIfAbsent(region.getResource(), r -> { + try { + return r.getInputStream(); + } catch (IOException e) { + exs.add(e); + return null; + } + }); + + if (!exs.isEmpty()) { + throw exs.get(0); + } - for (ResourceRegion region : resourceRegions) { - long start = region.getPosition(); - long end = start + region.getCount() - 1; - InputStream in = region.getResource().getInputStream(); - try { // Writing MIME header. println(out); print(out, "--" + boundaryString); @@ -200,11 +220,11 @@ private void writeResourceRegionCollection(Collection resourceRe // Printing content StreamUtils.copyRange(in, out, start, end); } - finally { + } finally { + for (InputStream in : cleanup) { try { in.close(); - } - catch (IOException ex) { + } catch (IOException ex) { // ignore } }