SpringBoot如何優雅的使用@ResponseBody返回圖片

可能是假程式猿發表於2018-09-21

我們都知道使用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來直接返回圖片。

 

相關文章