2015-08-18 1 views
4

У меня есть следующий код:Как скачать изображение с помощью шаблона отдыха?

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

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 показывает, как использовать IOUtils.copy() от commons-io, чтобы сделать некоторые грязные работы. Но вам нужно получить InputStream вашего файла ... Простым способом является использование HttpURLConnection. Есть tutorial с дополнительной информацией.

+0

я не расслышал, который technolohy можно использовать для загрузки файла – gstackoverflow

+0

** ResponseEntity responseEntity = restTemplate.getForObject ("http://img.championat.com/news/big/l/c/ujejn-runi_1439911080563855663. jpg ", ResponseEntity.class) ** тоже не работает – gstackoverflow

+0

Да, моя точка зрения ...' RestTemplate' - не самый подходящий инструмент для этой работы ... – pioto

8

изображение является массив, поэтому вам нужно использовать 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, и изображение будет сохранено в файл, как ожидалось.

+0

Недостатком этого подхода является то, что весь файл должен храниться в памяти. Для более мелких изображений, которые могут быть прекрасными, но вы все равно рискуете выдуть стек. – pioto

+0

Я понял из вопроса @ gstackoverflow, что это цель - преобразовать тело ответа в объект и перейти оттуда. Неясно, подходит ли файл-файл в памяти для его использования. Кстати, вы можете уточнить, как это сделать, я не уверен, что я следую (объекты AFAIK всегда должны быть созданы в куче, только ссылки могут быть локальными) – mzc

+0

извините, справа, я имел в виду кучу ... но да, в любом случае ... лучше всего использовать потоковые API, если это возможно, ИМХО, чтобы избежать длительного хранения таких вещей в памяти.Поскольку, похоже, его целью является просто сохранить удаленный файл в локальном файле, я не вижу необходимости в промежуточном 'byte []'? – pioto