web-dev-qa-db-ja.com

レストテンプレートを使用して画像をダウンロードする方法

私は次のコードを持っています:

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)

何が悪いの?

10
gstackoverflow

画像はバイト配列であるため、byte[].classの2番目の引数として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プロジェクトでこれをテストしましたが、イメージは期待どおりにファイルに保存されます。

17
mzc

単に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) {}
2
mancini0

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(ファイルなど)に書き出すためのさまざまなメソッドが存在します。

この答え は、_commons-io_のIOUtils.copy()を使用して、ダーティーな作業を行う方法を示しています。ただし、ファイルのInputStreamを取得する必要があります...簡単な方法は、 HttpURLConnection を使用することです。 tutorial と詳細情報があります。

1
pioto