问题描述
我的代码的目的是从第三方服务中检索图像。
我为下载的端点工作付出了一些努力,但只有部分成功。当我通过邮递员呼叫端点时,答案是.bin文件,但是我需要的是.png文件。最大的成功是能够获得一个.png文件,它也可以自定义名称。但是,个性化并非严格必要。
该项目使用初始化程序构建,并具有以下依赖项:
- spring-boot-starter-web;
- 龙目岛
- spring-boot-starter-webflux
- 反应器弹簧
以下是端点的源代码:
@GetMapping("/retrieve-image")
public Mono<byte[]> retrieveImage(ImageRequest request) throws ExecutionException,InterruptedException,IOException {
MultiValueMap<String,String> queryParams = new LinkedMultiValueMap<>();
queryParams.add("attribute",request.getAttribute()); // fake for query string setting.
Mono<byte[]> image = webClient
.get()
.uri(uriBuilder -> uriBuilder
.path(Endpoint.THIRD_PARTY_SERVICE_URI)
.queryParams(queryParams)
.build())
.accept(MediaType.valueOf(String.valueOf(MediaType.IMAGE_PNG)))
.exchange()
.flatMap(clientResponse -> clientResponse.bodyToMono(byte[].class)
.doOnSuccess(body -> {
if (clientResponse.statusCode().isError()) {
log.error("HttpStatusCode = {}",clientResponse.statusCode());
log.error("HttpHeaders = {}",clientResponse.headers().asHttpHeaders());
log.error("ResponseBody = {}",body);
}
}));
return image;
}
解决方法
您还可以将文件的mime类型添加到@GetMapping
批注的Produces部分中,它的外观应如下所示:
@GetMapping(path = "/retrieve-image",produces = "image/png")
此外,您可以将响应包装在Mono<byte[]>
中,而不是返回ResponseEntity<Resource>
。这使您可以添加标题并告诉浏览器文件名。例如:
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=image.png");
header.add("Access-Control-Expose-Headers","Content-Disposition");
return ResponseEntity.ok().
.headers(header)
.contentLength(Files.size(path))
.body(<<YOUR_FILE_HERE>>);
最后一个想法:如果将spring-boot-starter-web和spring-boot-starter-webflux都添加到您的依赖项中,则该应用程序可以运行,但是它不使用Webflux的Netty,而是普通的Tomcat。因此,您无法从反应式功能中受益。