|
|
|
@ -40,6 +40,7 @@ import org.springframework.util.StreamUtils; |
|
|
|
* or Collections of {@link ResourceRegion ResourceRegions}. |
|
|
|
* or Collections of {@link ResourceRegion ResourceRegions}. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Brian Clozel |
|
|
|
* @author Brian Clozel |
|
|
|
|
|
|
|
* @author Juergen Hoeller |
|
|
|
* @since 4.3 |
|
|
|
* @since 4.3 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> { |
|
|
|
public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> { |
|
|
|
@ -58,7 +59,7 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
Collection<ResourceRegion> regions = (Collection<ResourceRegion>) object; |
|
|
|
Collection<ResourceRegion> regions = (Collection<ResourceRegion>) object; |
|
|
|
if (regions.size() > 0) { |
|
|
|
if (!regions.isEmpty()) { |
|
|
|
resource = regions.iterator().next().getResource(); |
|
|
|
resource = regions.iterator().next().getResource(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -141,6 +142,7 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa |
|
|
|
protected void writeResourceRegion(ResourceRegion region, HttpOutputMessage outputMessage) throws IOException { |
|
|
|
protected void writeResourceRegion(ResourceRegion region, HttpOutputMessage outputMessage) throws IOException { |
|
|
|
Assert.notNull(region, "ResourceRegion must not be null"); |
|
|
|
Assert.notNull(region, "ResourceRegion must not be null"); |
|
|
|
HttpHeaders responseHeaders = outputMessage.getHeaders(); |
|
|
|
HttpHeaders responseHeaders = outputMessage.getHeaders(); |
|
|
|
|
|
|
|
|
|
|
|
long start = region.getPosition(); |
|
|
|
long start = region.getPosition(); |
|
|
|
long end = start + region.getCount() - 1; |
|
|
|
long end = start + region.getCount() - 1; |
|
|
|
Long resourceLength = region.getResource().contentLength(); |
|
|
|
Long resourceLength = region.getResource().contentLength(); |
|
|
|
@ -148,6 +150,7 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa |
|
|
|
long rangeLength = end - start + 1; |
|
|
|
long rangeLength = end - start + 1; |
|
|
|
responseHeaders.add("Content-Range", "bytes " + start + '-' + end + '/' + resourceLength); |
|
|
|
responseHeaders.add("Content-Range", "bytes " + start + '-' + end + '/' + resourceLength); |
|
|
|
responseHeaders.setContentLength(rangeLength); |
|
|
|
responseHeaders.setContentLength(rangeLength); |
|
|
|
|
|
|
|
|
|
|
|
InputStream in = region.getResource().getInputStream(); |
|
|
|
InputStream in = region.getResource().getInputStream(); |
|
|
|
try { |
|
|
|
try { |
|
|
|
StreamUtils.copyRange(in, outputMessage.getBody(), start, end); |
|
|
|
StreamUtils.copyRange(in, outputMessage.getBody(), start, end); |
|
|
|
@ -167,30 +170,43 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa |
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(resourceRegions, "Collection of ResourceRegion should not be null"); |
|
|
|
Assert.notNull(resourceRegions, "Collection of ResourceRegion should not be null"); |
|
|
|
HttpHeaders responseHeaders = outputMessage.getHeaders(); |
|
|
|
HttpHeaders responseHeaders = outputMessage.getHeaders(); |
|
|
|
|
|
|
|
|
|
|
|
MediaType contentType = responseHeaders.getContentType(); |
|
|
|
MediaType contentType = responseHeaders.getContentType(); |
|
|
|
String boundaryString = MimeTypeUtils.generateMultipartBoundaryString(); |
|
|
|
String boundaryString = MimeTypeUtils.generateMultipartBoundaryString(); |
|
|
|
responseHeaders.set(HttpHeaders.CONTENT_TYPE, "multipart/byteranges; boundary=" + boundaryString); |
|
|
|
responseHeaders.set(HttpHeaders.CONTENT_TYPE, "multipart/byteranges; boundary=" + boundaryString); |
|
|
|
OutputStream out = outputMessage.getBody(); |
|
|
|
OutputStream out = outputMessage.getBody(); |
|
|
|
|
|
|
|
|
|
|
|
for (ResourceRegion region : resourceRegions) { |
|
|
|
for (ResourceRegion region : resourceRegions) { |
|
|
|
long start = region.getPosition(); |
|
|
|
long start = region.getPosition(); |
|
|
|
long end = start + region.getCount() - 1; |
|
|
|
long end = start + region.getCount() - 1; |
|
|
|
InputStream in = region.getResource().getInputStream(); |
|
|
|
InputStream in = region.getResource().getInputStream(); |
|
|
|
// Writing MIME header.
|
|
|
|
try { |
|
|
|
println(out); |
|
|
|
// Writing MIME header.
|
|
|
|
print(out, "--" + boundaryString); |
|
|
|
|
|
|
|
println(out); |
|
|
|
|
|
|
|
if (contentType != null) { |
|
|
|
|
|
|
|
print(out, "Content-Type: " + contentType.toString()); |
|
|
|
|
|
|
|
println(out); |
|
|
|
println(out); |
|
|
|
|
|
|
|
print(out, "--" + boundaryString); |
|
|
|
|
|
|
|
println(out); |
|
|
|
|
|
|
|
if (contentType != null) { |
|
|
|
|
|
|
|
print(out, "Content-Type: " + contentType.toString()); |
|
|
|
|
|
|
|
println(out); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Long resourceLength = region.getResource().contentLength(); |
|
|
|
|
|
|
|
end = Math.min(end, resourceLength - 1); |
|
|
|
|
|
|
|
print(out, "Content-Range: bytes " + start + '-' + end + '/' + resourceLength); |
|
|
|
|
|
|
|
println(out); |
|
|
|
|
|
|
|
println(out); |
|
|
|
|
|
|
|
// Printing content
|
|
|
|
|
|
|
|
StreamUtils.copyRange(in, out, start, end); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
finally { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
in.close(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (IOException ex) { |
|
|
|
|
|
|
|
// ignore
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Long resourceLength = region.getResource().contentLength(); |
|
|
|
|
|
|
|
end = Math.min(end, resourceLength - 1); |
|
|
|
|
|
|
|
print(out, "Content-Range: bytes " + start + '-' + end + '/' + resourceLength); |
|
|
|
|
|
|
|
println(out); |
|
|
|
|
|
|
|
println(out); |
|
|
|
|
|
|
|
// Printing content
|
|
|
|
|
|
|
|
StreamUtils.copyRange(in, out, start, end); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
println(out); |
|
|
|
println(out); |
|
|
|
print(out, "--" + boundaryString + "--"); |
|
|
|
print(out, "--" + boundaryString + "--"); |
|
|
|
} |
|
|
|
} |
|
|
|
|