ZetCode

在 Spring Boot 中提供图像文件

最后修改于 2023 年 7 月 31 日

在本文中,我们将展示如何在 Spring Boot RESTful Web 应用程序中提供图像文件。图像是位于 resources 目录中的 JPEG 文件。

Spring 是一个用于开发 Java 企业应用程序的 Java 应用程序框架。它也有助于集成各种企业组件。Spring Boot 使得创建具有最少设置要求的、基于 Spring 的、生产级应用程序和服务变得容易。

我们将展示三种将图像数据发送到客户端的方法。

Spring 图像示例

Web 应用程序在 src/main/resources/image 目录中包含一个 sid.jpg 文件。ClassPathResource 用于获取图像文件。

build.gradle
...
src
├── main
│   ├── java
│   │   └── com
│   │       └── zetcode
│   │           ├── Application.java
│   │           └── controller
│   │               └── MyController.java
│   └── resources
│       └── image
│           └── sid.jpg
└── test
    └── java

这是项目结构。

build.gradle
plugins {
    id 'org.springframework.boot' version '3.1.1'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
}

group = 'com.zetcode'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

这是 Gradle 构建文件。spring-boot-starter-web 是一个用于使用 Spring MVC 构建 Web 应用程序的启动器。它使用 Tomcat 作为默认的嵌入式服务器。

com/zetcode/Application.java
package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Application 设置 Spring Boot 应用程序。@SpringBootApplication 启用组件扫描和自动配置。

使用 HttpServletResponse 提供图像

在第一种情况下,我们直接写入 HttpServletResponse

com/zetcode/controller/MyController.java
package com.zetcode.controller;

import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
public class MyController {

    @RequestMapping(value = "/sid", method = RequestMethod.GET,
            produces = MediaType.IMAGE_JPEG_VALUE)

    public void getImage(HttpServletResponse response) throws IOException {

        var imgFile = new ClassPathResource("image/sid.jpg");

        response.setContentType(MediaType.IMAGE_JPEG_VALUE);
        StreamUtils.copy(imgFile.getInputStream(), response.getOutputStream());
    }
}

在此控制器中,我们获取图像资源并将其直接写入响应对象。

var imgFile = new ClassPathResource("image/sid.jpg");

我们使用 ClassPathResource 从 classpath(src/main/resources 目录位于 Java classpath 中)中获取图像资源。

response.setContentType(MediaType.IMAGE_JPEG_VALUE);

响应的内容类型设置为 MediaType.IMAGE_JPEG_VALUE

StreamUtils.copy(imgFile.getInputStream(), response.getOutputStream());

使用 StreamUtils,我们将数据从图像复制到响应对象。

使用 ResponseEntity 提供图像

在第二种情况下,我们使用 ResponseEntity

com/zetcode/controller/MyController.java
package com.zetcode.controller;

import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
public class MyController {

    @RequestMapping(value = "/sid", method = RequestMethod.GET,
            produces = MediaType.IMAGE_JPEG_VALUE)
    public ResponseEntity<byte[]> getImage() throws IOException {

        var imgFile = new ClassPathResource("image/sid.jpg");
        byte[] bytes = StreamUtils.copyToByteArray(imgFile.getInputStream());

        return ResponseEntity
                .ok()
                .contentType(MediaType.IMAGE_JPEG)
                .body(bytes);
    }
}

getImage 方法的返回类型设置为 ResponseEntity<byte[]>

byte[] bytes = StreamUtils.copyToByteArray(imgFile.getInputStream());

使用 StreamUtils.copyToByteArray,我们将图像数据复制到一个字节数组中。

return ResponseEntity
        .ok()
        .contentType(MediaType.IMAGE_JPEG)
        .body(bytes);

字节数组被提供给 ResponseEntity 的主体。

使用 ResponseEntity 和 InputStreamResource 提供图像

在第三种情况下,我们使用 ResponseEntityInputStreamResourceInputStreamResource 是 Spring 对底层资源的抽象。

com/zetcode/controller/MyController.java
package com.zetcode.controller;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
public class MyController {

    @RequestMapping(value = "/sid", method = RequestMethod.GET,
            produces = MediaType.IMAGE_JPEG_VALUE)
    public ResponseEntity<InputStreamResource> getImage() throws IOException {

        var imgFile = new ClassPathResource("image/sid.jpg");

        return ResponseEntity
                .ok()
                .contentType(MediaType.IMAGE_JPEG)
                .body(new InputStreamResource(imgFile.getInputStream()));
    }
}

getImage 方法的返回类型设置为 ResponseEntity<InputStreamResource>

return ResponseEntity
        .ok()
        .contentType(MediaType.IMAGE_JPEG)
        .body(new InputStreamResource(imgFile.getInputStream()));

ResponseEntity 的主体返回一个 InputStreamResource

$ ./gradlew bootRun

我们启动 Spring Boot 应用程序。

我们导航到 https://:8080/sid 以在浏览器中显示图像。

在本文中,我们展示了如何从 Spring Boot 应用程序将图像数据发送到客户端。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出 所有 Spring Boot 教程