首页 文章

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

提问于
浏览
10

使用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时

Headers 没有添加,所以错误是预期的(请指导我这个)

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客户端 .

5 回答

  • 2

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

    #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

    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" />
        
    <a href="https://localhost/rest/getPdfBatchAsBytes/pdf-id.pdf">Download pdf</a> </body> </html>

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

  • 18

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

    在你的 Spring 天配置 .

  • 3

    这是我为此写的方法 .

    我需要在页面上内嵌显示图像,并可选择将其下载到客户端,因此我使用可选参数为其设置适当的 Headers .

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

相关问题