如何在Spring中从Web服务发送图像

时间:2011-12-28 12:45:44

标签: java json spring spring-mvc

使用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来测试Web服务。

但是当我点击http://localhost:8080/my-war-name/rest/image网址时。

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).

我曾经遇到过以下错误

  

此请求标识的资源仅具有此功能   根据请求“accept”headers()

生成具有不可接受特征的响应

我跟着 http://krams915.blogspot.com/2011/02/spring-3-rest-web-service-provider-and.html教程。

我的要求是以字节格式将图像发送到Android客户端。

6 个答案:

答案 0 :(得分:17)

除了灵魂检查提供的答案。 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);
    }
}

答案 1 :(得分:3)

#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);
    }
}

答案 2 :(得分:2)

请参阅this article on the excellent baeldung.com website

您可以在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从数据库中检索img / pdf Blob。

对pdf文件的类似处理,但您需要在内容类型中使用MediaType.APPLICATION_PDF_VALUE。您可以从html页面引用图像文件或pdf文件:

<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>

...或者您可以直接从浏览器调用Web服务方法。

答案 3 :(得分:1)

删除转换为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>

在你的春季配置中。

答案 4 :(得分:0)

这是我为此写的方法。

我需要在页面上内嵌显示图像,并可选择将其下载到客户端,因此我选择一个可选参数来设置相应的标题。

Document是我表示文档的实体模型。我将文件本身存储在以存储该文档的记录的ID命名的光盘上。原始文件名和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();

}

答案 5 :(得分:0)

如果您使用的是Spring Boot,只需将图像放在类路径的正确文件夹中即可。选中https://www.baeldung.com/spring-mvc-static-resources