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

Posted

技术标签:

【中文标题】是否有更改以返回像 response.png 而不是 response.bin 这样的 png 文件【英文标题】:Is there a change to return a png file like response.png instead of response.bin 【发布时间】:2021-01-17 03:05:30 【问题描述】:

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

我为下载端点工作而挣扎了一点,但只成功了一部分。当我通过邮递员调用端点时,答案是一个 .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;

【问题讨论】:

AFAIK,spring-web 不建议在同一个应用程序中与spring-webflux 一起使用。 ***.com/questions/53883037/… docs.spring.io/spring-framework/docs/current/… 。引用文档:如果您有一个调用远程服务的 Spring MVC 应用程序,请尝试响应式 WebClient。您可以直接从 Spring MVC 控制器方法返回反应类型(Reactor、RxJava 或其他)。 @VladimirShefer 你说的“梨树”是什么意思,什么是“邮寄梨”? @meberhard 对不起。这是一个错字。 【参考方案1】:

您还可以将文件的 mime 类型添加到 @GetMapping 注释的生产部分,它应该如下所示:

@GetMapping(path = "/retrieve-image",
        produces = "image/png")

此外,您可以将回复包装在ResponseEntity&lt;Resource&gt; 中,而不是返回Mono&lt;byte[]&gt;。这使您可以添加标题并告诉浏览器您的文件名。例如:

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。因此,您不会从响应式功能中受益。

【讨论】:

感谢您的修复。在我的端点中,我使用 Mono,带有 pojo 或 byte[]。您可以在示例中编写整个端点吗?您的解决方案有什么好处? ..我正在编写一个带有rest控制器的Web服务器,但我需要WebClient来调用第三方服务; RestTemplate 非常旧且不适合...您将如何重新排列依赖项?有什么好处?谢谢。

以上是关于是否有更改以返回像 response.png 而不是 response.bin 这样的 png 文件的主要内容,如果未能解决你的问题,请参考以下文章

vba:以 xlsm 文件格式保存而不更改活动工作簿

在编译时重命名符号而不以跨平台方式更改代码

使用 Sammy.js 取消路由而不影响历史

是否可以使用 SQLite 来存储翻译而不是像 strings.xml 这样的 XML 资源

在 iOS 7 中更新导航栏而不更改视图

在运行时更改字体