我们都知道使用HttpServletResponse可以通过输出流的方式来向前台输出图片。那么使用Spring Boot之后,我们应该如何来优雅的简化我们的代码呢?
首先,Spring Boot依然使用的是Spring MVC作为Controller层,那么通过Spring Boot的自动配置,可以很轻松的配置SpringMVC,这里我们使用Maven搭建Spring Boot项目,直接引入web依赖之后,自动配置即可。(使用Spring Boot 1.5.14版本)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
然后,写一个Controller类,包括一个方法,如下:
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@Controller
@RequestMapping(value = "/image")
public class ImageController {
@RequestMapping(value = "/get",produces = MediaType.IMAGE_JPEG_VALUE)
@ResponseBody
public byte[] getImage() throws IOException {
File file = new File("D:/test.jpg");
FileInputStream inputStream = new FileInputStream(file);
byte[] bytes = new byte[inputStream.available()];
inputStream.read(bytes, 0, inputStream.available());
return bytes;
}
}
解释一下,我们首先在@RequestMapping上加入produces告诉Spring,我们要返回的MediaType是一个图片(image/jpeg),然后加上@ResponseBody注解,方法返回byte[],然后将图片读进byte[]。如果不加produces会报错,有兴趣自己试。
前台测试一下,没有问题。但是有的人觉得,方法返回byte[]是不是不够优雅?没关系,SpringBoot的MVC还给我们提供了更优雅的方式,代码如下:
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@Controller
@RequestMapping(value = "/image")
public class ImageController {
@RequestMapping(value = "/get",produces = MediaType.IMAGE_JPEG_VALUE)
@ResponseBody
public BufferedImage getImage() throws IOException {
return ImageIO.read(new FileInputStream(new File("D:/test.jpg")));
}
}
怎么样,一行代码就解决了问题,是不是更优雅?其他人看到你的代码,也一眼就知道你是返回的一张图片。
这里稍做解释,我们使用JAVA 自带的ImageIO来读取图片,返回一个BufferedImage对象,同样使用produces来告诉Spring我要返回一个图片。
如果感兴趣,想知道其中的实现原理,其实很简单,加了@ResponseBody注解之后,SpringMVC 不再去找视图,而是通过
HttpMessageConverter这个接口的实现类而进行消息转化,当你的方法返回了byte[] 的时候,Spring则判断使用ByteArrayHttpMessageConverter来做消息转化,返回到前台,同样,我们返回Json和xml的时候,也是使用的(如果没有自定义配置)spring自带的MappingJackson2HttpMessageConverter来做消息转化。同理,Spring还提供了BufferedImageHttpMessageConverter这个实现,所以我们才能够通过返回BufferedImage来直接返回图片。