使用 rest web 服务生成部分内容 (206) 作为 zip 文件分块下载输出的问题
Issue in producing a Partial Content(206) as output for chunked download of a zip file using rest web services
我已经编写了一个 rest web 服务来使用 spring boot(2.0.5.RELEASE) 使用 mime 类型 application_octet_stream
以块的形式生成一个 zip 文件,但我无法获得当我使用如下 curl 命令指定范围时,partial_content(206)
作为输出,但我得到 200(OK) 作为响应,即我无法按块检索文件。
curl http://localhost:8080/resource/getlist -i -H "Range: bytes=0-100"
PS:spring 启动应用程序部署在外部码头服务器上,我没有使用嵌入式 tomcat 和码头服务器,其中排除在 pom.xml.This是由于各种设计原因。
我需要在外部码头服务器上进行任何配置吗additions/modifications?
代码如下
@RestController
@RequestMapping("/resource")
public class ListResource {
/* Logger **/
private static final Logger _LOG = LoggerFactory.getLogger(ListResource.class);
@Autowired
private AppContext appContext;
private static final String DATE_FORMAT_FOR_ETAG = "yyyy-MM-dd HH:mm:ss'Z'";
private static final DateFormat eTagDateFormat = new SimpleDateFormat(DATE_FORMAT_FOR_ETAG, Locale.US);
private static final String ACCEPT_RANGES_BYTES = "bytes";
@RequestMapping(path = "/getlist", method = RequestMethod.HEAD)
public ResponseEntity<?> fetchListHead() throws IOException {
return fetchList(true);
}
@RequestMapping(path = "/getlist", method = RequestMethod.GET,produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<?> fetchListGet() throws IOException {
return fetchList(false);
}
private ResponseEntity<?> fetchList(final boolean justHead) throws IOException {
File file = null;
try {
file = new File("/home/resource/hello.zip");
byte[] readBytes = Files.readAllBytes(file.toPath());
ByteArrayResource resource = new ByteArrayResource(readBytes);
ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"")
.header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_BYTES)
.lastModified(new Date().getTime())
.eTag(getETag(file))
.cacheControl(CacheControl.maxAge(3600, TimeUnit.SECONDS).cachePublic().mustRevalidate())
.contentLength(file.length())
.contentType(MediaType.parseMediaType(MediaType.APPLICATION_OCTET_STREAM_VALUE));
return justHead ? responseBuilder.build() : responseBuilder.body(resource);
} catch (Exception e) {
_LOG.error("Error in gettingResource:{}", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
private String getETag(File file) {
String tag = "";
if (file != null) {
tag = eTagDateFormat.format(new Date(file.getAbsoluteFile().lastModified()));
}
return tag;
}
}
Jetty 服务器的作用不是处理对动态内容(您的 REST 服务)的远程请求。
Jetty 提供的唯一远程请求支持是...
- 具有重叠范围的传入请求范围在被分派到上下文之前合并为合理的范围。
- 无效的请求范围(例如负数)导致 BadMessageException 和对用户代理的 400 响应。
- 通过
DefaultServlet
提供的静态内容支持远程请求。
由您的动态端点(您的其余 API)读取请求的范围并确定是否支持提供这些特定范围,然后提供它、拒绝范围或提供整个范围内容.
如果您认为这是 Jetty 应该支持的功能,请随时在 https://github.com/eclipse/jetty.project/issues
提交增强请求
我已经编写了一个 rest web 服务来使用 spring boot(2.0.5.RELEASE) 使用 mime 类型 application_octet_stream
以块的形式生成一个 zip 文件,但我无法获得当我使用如下 curl 命令指定范围时,partial_content(206)
作为输出,但我得到 200(OK) 作为响应,即我无法按块检索文件。
curl http://localhost:8080/resource/getlist -i -H "Range: bytes=0-100"
PS:spring 启动应用程序部署在外部码头服务器上,我没有使用嵌入式 tomcat 和码头服务器,其中排除在 pom.xml.This是由于各种设计原因。
我需要在外部码头服务器上进行任何配置吗additions/modifications?
代码如下
@RestController
@RequestMapping("/resource")
public class ListResource {
/* Logger **/
private static final Logger _LOG = LoggerFactory.getLogger(ListResource.class);
@Autowired
private AppContext appContext;
private static final String DATE_FORMAT_FOR_ETAG = "yyyy-MM-dd HH:mm:ss'Z'";
private static final DateFormat eTagDateFormat = new SimpleDateFormat(DATE_FORMAT_FOR_ETAG, Locale.US);
private static final String ACCEPT_RANGES_BYTES = "bytes";
@RequestMapping(path = "/getlist", method = RequestMethod.HEAD)
public ResponseEntity<?> fetchListHead() throws IOException {
return fetchList(true);
}
@RequestMapping(path = "/getlist", method = RequestMethod.GET,produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<?> fetchListGet() throws IOException {
return fetchList(false);
}
private ResponseEntity<?> fetchList(final boolean justHead) throws IOException {
File file = null;
try {
file = new File("/home/resource/hello.zip");
byte[] readBytes = Files.readAllBytes(file.toPath());
ByteArrayResource resource = new ByteArrayResource(readBytes);
ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"")
.header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_BYTES)
.lastModified(new Date().getTime())
.eTag(getETag(file))
.cacheControl(CacheControl.maxAge(3600, TimeUnit.SECONDS).cachePublic().mustRevalidate())
.contentLength(file.length())
.contentType(MediaType.parseMediaType(MediaType.APPLICATION_OCTET_STREAM_VALUE));
return justHead ? responseBuilder.build() : responseBuilder.body(resource);
} catch (Exception e) {
_LOG.error("Error in gettingResource:{}", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
private String getETag(File file) {
String tag = "";
if (file != null) {
tag = eTagDateFormat.format(new Date(file.getAbsoluteFile().lastModified()));
}
return tag;
}
}
Jetty 服务器的作用不是处理对动态内容(您的 REST 服务)的远程请求。
Jetty 提供的唯一远程请求支持是...
- 具有重叠范围的传入请求范围在被分派到上下文之前合并为合理的范围。
- 无效的请求范围(例如负数)导致 BadMessageException 和对用户代理的 400 响应。
- 通过
DefaultServlet
提供的静态内容支持远程请求。
由您的动态端点(您的其余 API)读取请求的范围并确定是否支持提供这些特定范围,然后提供它、拒绝范围或提供整个范围内容.
如果您认为这是 Jetty 应该支持的功能,请随时在 https://github.com/eclipse/jetty.project/issues
提交增强请求