Как отправить изображение из веб-сервиса весной - PullRequest
10 голосов
/ 28 декабря 2011

Возникла проблема при отправке изображения с помощью Spring Web Service.

Я написал контроллер, как показано ниже

@Controller
public class WebService {

    @RequestMapping(value = "/image", headers = "Accept=image/jpeg, image/jpg, image/png, image/gif", method = RequestMethod.GET)
    public @ResponseBody byte[] getImage() {
        try {
            InputStream inputStream = this.getClass().getResourceAsStream("myimage.jpg");
            BufferedImage bufferedImage = ImageIO.read(inputStream);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write( bufferedImage  , "jpg", byteArrayOutputStream);
            return byteArrayOutputStream.toByteArray();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

@ResponseBody преобразует ответ в JSON.

Я использую RestClient для тестирования веб-службы.

Но когда я нажимаю на http://localhost:8080/my-war-name/rest/image URL.

Header 
Accept=image/jpg

Я столкнулся со следующей ошибкой на RestClient

Ошибка преобразования тела ответа в строку с использованием кодировки windows-1252. Тело ответа не установлено!

Когда я использую браузеры Chrome и Firefox

Заголовки не добавляются, поэтому ожидается ошибка (пожалуйста, сообщите мне об этом)

HTTP Status 405 - Request method 'GET' not supported

type Status report

message Request method 'GET' not supported

description The specified HTTP method is not allowed for the requested resource (Request method 'GET' not supported).

Я тоже однажды столкнулся с ошибкой

Ресурс, указанный в этом запросе, способен только генерации ответов с признаками, не приемлемыми по запросу «принять» заголовки ()

Я следовал http://krams915.blogspot.com/2011/02/spring-3-rest-web-service-provider-and.html учебник.

Мое требование - отправить изображение в байтовом формате на Android Client.

Ответы [ 5 ]

17 голосов
/ 20 сентября 2012

В дополнение к ответу предоставлен soulcheck.Spring добавил , создает свойство к аннотации @ RequestMapping .Поэтому решение стало проще:

@RequestMapping(value = "/image", method = RequestMethod.GET, produces = "image/jpg")
public @ResponseBody byte[] getFile()  {
    try {
        // Retrieve image from the classpath.
        InputStream is = this.getClass().getResourceAsStream("/test.jpg"); 

        // Prepare buffered image.
        BufferedImage img = ImageIO.read(is);

        // Create a byte array output stream.
        ByteArrayOutputStream bao = new ByteArrayOutputStream();

        // Write to output stream
        ImageIO.write(img, "jpg", bao);

        return bao.toByteArray();
    } catch (IOException e) {
        logger.error(e);
        throw new RuntimeException(e);
    }
}
3 голосов
/ 02 ноября 2017

См. эту статью на отличном сайте baeldung.com .

Вы можете использовать следующий код в Spring Controller:

@RequestMapping(value = "/rest/getImgAsBytes/{id}", method = RequestMethod.GET)
public ResponseEntity<byte[]> getImgAsBytes(@PathVariable("id") final Long id, final HttpServletResponse response) {
    HttpHeaders headers = new HttpHeaders();
    headers.setCacheControl(CacheControl.noCache().getHeaderValue());
    response.setContentType(MediaType.IMAGE_JPEG_VALUE);

    try (InputStream in = imageService.getImageById(id);) { // Spring service call
        if (in != null) {
            byte[] media = IOUtils.toByteArray(in);
            ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK);
            return responseEntity;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return new ResponseEntity<>(null, headers, HttpStatus.NOT_FOUND);
}

Примечания: IOUtils поставляется из библиотеки Common-io Apache. Я использую Spring Service для получения BLOB-объектов img / pdf из базы данных.

Аналогичная обработка для файлов PDF, за исключением того, что вам необходимо использовать MediaType.APPLICATION_PDF_VALUE в типе контента. И вы можете ссылаться на файл изображения или PDF-файл со страницы HTML:

<html>
  <head>
  </head>
  <body>
    <img src="https://localhost/rest/getImgDetectionAsBytes/img-id.jpg" />
    <br/>
    <a href="https://localhost/rest/getPdfBatchAsBytes/pdf-id.pdf">Download pdf</a>
  </body>
</html>

... или вы можете вызвать метод веб-службы прямо из браузера.

3 голосов
/ 14 ноября 2012

Ответ от #soulcheck частично верен.Конфигурация не будет работать в последней версии Spring, поскольку она будет конфликтовать с элементом mvc-annotation.Попробуйте приведенную ниже конфигурацию.

<mvc:annotation-driven>
  <mvc:message-converters register-defaults="true">
    <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
  </mvc:message-converters>
</mvc:annotation-driven>

Как только вы настроите конфигурацию в вашем конфигурационном файлеКод ниже будет работать:

@RequestMapping(value = "/image", headers = "Accept=image/jpeg, image/jpg, image/png, image/gif", method = RequestMethod.GET)
public @ResponseBody BufferedImage getImage() {
    try {
        InputStream inputStream = this.getClass().getResourceAsStream("myimage.jpg");
        return ImageIO.read(inputStream);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
1 голос
/ 28 декабря 2011

Отбросить преобразование в json и отправить байтовый массив как есть.

Единственным недостатком является то, что он отправляет application/octet-stream тип содержимого по умолчанию.

Если вам это не подходит, вы можете использовать BufferedImageHttpMessageConverter , который может отправлять изображения любого типа, поддерживаемые зарегистрированными программами чтения изображений.

Затем вы можете изменить свой метод на:

@RequestMapping(value = "/image", headers = "Accept=image/jpeg, image/jpg, image/png, image/gif", method = RequestMethod.GET)
public @ResponseBody BufferedImage getImage() {
    try {
        InputStream inputStream = this.getClass().getResourceAsStream("myimage.jpg");
        return ImageIO.read(inputStream);


    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

при наличии:

 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="order" value="1"/>
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
        </list>
    </property>
</bean>

в конфигурации пружины.

0 голосов
/ 28 декабря 2011

Вот метод, который я написал для этого.

Мне нужно было как отобразить встроенное изображение на странице, так и при необходимости загрузить его клиенту, поэтому я использую необязательный параметр, чтобы установить соответствующий заголовок для этого.

Document - это моя модель сущности для представления документов.У меня сами файлы хранятся на диске, названном в честь идентификатора записи, в которой хранится этот документ.Исходное имя файла и тип mime хранятся в объекте Document.

@RequestMapping("/document/{docId}")
public void downloadFile(@PathVariable Integer docId, @RequestParam(value="inline", required=false) Boolean inline, HttpServletResponse resp) throws IOException {

    Document doc = Document.findDocument(docId);

    File outputFile = new File(Constants.UPLOAD_DIR + "/" + docId);

    resp.reset();
    if (inline == null) {
        resp.setHeader("Content-Disposition", "attachment; filename=\"" + doc.getFilename() + "\"");
    }
    resp.setContentType(doc.getContentType());
    resp.setContentLength((int)outputFile.length());

    BufferedInputStream in = new BufferedInputStream(new FileInputStream(outputFile));

    FileCopyUtils.copy(in, resp.getOutputStream());
    resp.flushBuffer();

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...