SpringBoot如何優雅的使用@ResponseBody返回圖片
阿新 • • 發佈:2018-12-11
我們都知道使用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來直接返回圖片。