Andy Wilkinson opened SPR-15789 and commented
I've just been pleased to learn that WebFlux automatically supports range requests to a request mapping method that returns a Resource:
@RequestMapping(path = "/")
public Resource test() {
return new ByteArrayResource(new byte[] {'a', 'b', 'c', 'd', 'e', 'f'});
}
$ curl localhost:8080 -H "Range: bytes=2-4" -i
HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Content-Type: application/octet-stream
Content-Range: bytes 2-4/6
Content-Length: 3
cde
Unfortunately, if the same controller is implemented using Spring MVC, the full resource content is returned:
$ curl localhost:8080 -H "Range: bytes=2-4" -i
HTTP/1.1 200
Content-Type: application/json
Content-Length: 6
Date: Tue, 18 Jul 2017 13:03:31 GMT
abcdef
It would be beneficial to Boot 2.0's new actuator endpoint infrastructure if Spring MVC offered the same capabilities as WebFlux here.
Affects: 5.0 RC2
Issue Links: - #18407 Add support for http byte-range requests for non-static resources ("is duplicated by")
Referenced from: commits https://github.com/spring-projects/spring-framework/commit/582014e944002609b562f6e4998935c06bbe6922
1 votes, 3 watchers
Comment From: peter-lyons-kehl
Side notes: Are you figuring out how to implement partial downloads (HTTP range)?
In addition to returning Resource, your controller method needs to be annotated with @ResponseBody, too. Otherwise it upsets Spring and it chains the request as if the URL was repeated.
If you do return a Resource, Spring ignores any content type you set by servletResponse.setContentType(String). It probably auto-detects the content type instead.
Alternatively, don't use @ResponseBody and return type org.springframework.http<Resource> and generate it like (in Kotlin):
return ResponseEntity
.ok()
.contentLength(resourceLength)
.contentType(
MediaType.parseMediaType("application/octet-stream"))
.body(fixedLengthInputStream)
If you use InputStreamResource, extend it (for example as an anonymous class) and override its contentLength(), too.