Spring Boot + Zuul:如何从RESTful服务提供的文件流中获取"Content-length"header?

Spring Boot + Zuul: how to get the "Content-length" header from a file stream provided by RESTful services?

我正在使用 Spring Cloud 和 Zuul 代理作为微服务提供的 RESTful 服务的网关。当我直接向微服务实例执行请求时,所有 header 都按我的预期提供。但是,当 Zuul 代理相同的请求时,header "Content-length" 被删除。我对此做了一些研究,我看到 Zuul 添加了 header "Transfer-Encoding" 作为 "chunked" 并且在这种情况下 header Content-length 被省略了(Content-Length is being stripped, ).

但是,我确实需要获得 RESTful 服务提供的 "Content-length"。这个请求也必须由 Zuul 代理(我有很多微服务实例,所以我不会直接访问它们)。

这是我的微服务中的方法:

@RequestMapping(value = "/jobresult/{id}", method = RequestMethod.GET)
@Timed
public ResponseEntity<InputStreamResource> downloadJobResult(@PathVariable Long id) {
    Job job = jobService.findOne(id);
    File file = new File(job.getTargetFile());
    try {
       return ResponseEntity.ok().contentLength(file.length()).contentType(MediaType.APPLICATION_OCTET_STREAM).body(new InputStreamResource(new FileInputStream(file)));
    } catch (FileNotFoundException e) {
       log.error(e.getMessage(), e);
    }
}

例如,对/api/jobresult/1的请求正确提供了header "Content-length",但是对/service/api/jobresult/1的请求(由Zuul路由)不显示这个header 并将 "Transfer-Encoding" 修改为 "chunked"。

很遗憾,我找不到这个问题的答案。为了使事情正常进行,我写了一个替代 header "X-Content-Length" 包含文件大小。

这样,Zuul就不会把header擦掉,我就可以在客户端读取了。由于我可以控制两者,所以这不是问题。但在其他情况下,客户应该知道这样 header。

来自 Spring Cloud Netflix 代码的 Zuul 响应过滤器导致了这个问题。

解决方案

在 src/main/resources 中添加 application.properties 文件(如果您没有)并添加以下行:

zuul.set-content-length=true