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

Ket*_*tan 10 java spring json 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

@ResponseBody 将响应转换为JSON.

我正在使用RestClient来测试Web服务.

但是当我点击http://localhost:8080/my-war-name/rest/imageURL时.

Header 
Accept=image/jpg
Run Code Online (Sandbox Code Playgroud)

我在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"标头()生成具有不可接受特征的响应

我已经关注了 http://krams915.blogspot.com/2011/02/spring-3-rest-web-service-provider-and.html教程.

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

小智 18

除了灵魂检查提供的答案.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);
    }
}
Run Code Online (Sandbox Code Playgroud)


jsf*_*jsf 6

#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>
Run Code Online (Sandbox Code Playgroud)

在配置文件中完成上述配置后。以下代码将起作用:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)


sou*_*eck 2

删除对 j​​son 的转换并按原样发送字节数组。

唯一的缺点是它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);
    }
}
Run Code Online (Sandbox Code Playgroud)

同时拥有:

 <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>
Run Code Online (Sandbox Code Playgroud)

在你的弹簧配置中。