如何使用rest模板下载图像?
Posted
技术标签:
【中文标题】如何使用rest模板下载图像?【英文标题】:How to download image using rest template? 【发布时间】:2015-08-18 18:36:20 【问题描述】:我有以下代码:
restTemplate.getForObject("http://img.championat.com/news/big/l/c/ujejn-runi_1439911080563855663.jpg", File.class);
我特别拍摄了不需要授权且绝对可供所有人使用的图像。
执行以下代码时,我看到以下堆栈跟踪:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class java.io.File] and content type [image/jpeg]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:108)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:559)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:512)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:243)
at com.terminal.controller.CreateCompanyController.handleFileUpload(CreateCompanyController.java:615)
我做错了什么?
【问题讨论】:
【参考方案1】:图像是一个字节数组,所以你需要使用byte[].class
对象作为RestTemplate.getForObject
的第二个参数:
String url = "http://img.championat.com/news/big/l/c/ujejn-runi_1439911080563855663.jpg";
byte[] imageBytes = restTemplate.getForObject(url, byte[].class);
Files.write(Paths.get("image.jpg"), imageBytes);
要使其正常工作,您需要在应用程序配置中配置 ByteArrayHttpMessageConverter
:
@Bean
public RestTemplate restTemplate(List<HttpMessageConverter<?>> messageConverters)
return new RestTemplate(messageConverters);
@Bean
public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter()
return new ByteArrayHttpMessageConverter();
我已经在 Spring Boot 项目中对此进行了测试,并且图像已按预期保存到文件中。
【讨论】:
这种方法的缺点是必须将整个文件存储在内存中。对于较小的图像可能没问题,但您仍然可能冒着炸毁堆栈的风险。 我从@g*** 的问题中了解到这是目标 - 将响应主体转换为对象并从那里开始。目前尚不清楚他的用例是否可以接受将文件对象放在内存中。顺便说一句,你能否澄清一下吹堆栈,我不确定我是否遵循(AFAIK 对象应始终在堆上创建,只有引用可以是本地的) 抱歉,你说得对,我的意思是堆...但是是的,无论如何...最好尽可能使用流式 API,恕我直言,以避免将此类内容长期保存在内存中.由于他的目标似乎只是将远程文件保存到本地文件,因此我认为不需要中间byte[]
?
我同意,如果您想处理更大的文件或大流量,流式传输到文件是唯一的方法。更多 Spring 示例:***.com/questions/5673260/…【参考方案2】:
如果你只是需要从 URL 中获取图像,Java 自带 javax.imageio.ImageIO 类,其中包含此方法签名:
public static BufferedImage read(URL var0) throws IOException;
示例使用:
try
BufferedImage image = ImageIO.read(new URL("http://www.foo.com/icon.png"));
int height = image.getHeight();
int width = image.getWidth();
catch (IOException e)
【讨论】:
【参考方案3】:RestTemplate
期望一个类(例如,一些内存中的表示)将来自服务器的响应转换为。例如,它可以转换如下响应:
id: 1, name: "someone"
进入类似的类:
class NamedThing
private int id;
private String name;
// getters/setters go here
通过调用:
NamedThing thing = restTemplate.getForObject("/some/url", NamedThing.class);
但是,您似乎真正想做的是从服务器获取响应并将其直接流式传输到文件中。有多种方法可以将您的 HTTP 请求的响应正文获取为类似 InputStream
的内容,您可以逐步读取它,然后将其写入 OutputStream
(例如您的文件)。
This answer 展示了如何使用来自commons-io
的IOUtils.copy()
来做一些肮脏的工作。但是您需要获取文件的 InputStream... 一个简单的方法是使用HttpURLConnection
。有一个tutorial 提供更多信息。
【讨论】:
我没有找到可以使用哪种技术来下载文件 ResponseEntity以上是关于如何使用rest模板下载图像?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 AWS 开发工具包从 S3 下载对象 - RESTful
如何正确实现使用 Spring MVC\Boot 返回图像列表的 REST 服务?
如何使用 DJango Rest Framework 上传多个图像?
如何在 Laravel REST API 中使用 PUT 方法更新图像?