是否有更改要返回像response.png这样的png文件而不是response.bin

问题描述

我的代码的目的是从第三方服务中检索图像。

我为下载的端点工作付出了一些努力,但只有部分成功。当我通过邮递员呼叫端点时,答案是.bin文件,但是我需要的是.png文件。最大的成功是能够获得一个.png文件,它也可以自定义名称。但是,个性化并非严格必要。

该项目使用初始化程序构建,并具有以下依赖项:

以下是端点的源代码

@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。因此,您无法从反应式功能中受益。