【Spring Boot 3】【Web】返回图片

【Spring Boot 3】【Web】返回图片

背景

软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费或多或少的时间、检索不止一篇资料才能得出一个可工作的DEMO,这占用了我大量的时间精力。因此本文旨在通过一篇文章即能还原出可工作的、甚至可用于生产的DEMO,期望初学者能尽快地迈过0到1的这一步骤,并在此基础上不断深化对相关知识的理解。

为达以上目的,本文会将开发环境、工程目录结构、开发步骤及源码尽量全面地展现出来,文字描述能简则简,能用代码注释的绝不在正文中再啰嗦一遍,正文仅对必要且关键的信息做重点描述。

介绍

本文介绍开发 Spring Boot Web 应用时如何返回图片给前端显示。

开发环境

分类 名称 版本
操作系统 Windows Windows 11
JDK Oracle JDK 21.0.1
IDE IntelliJ IDEA 2023.3.7
构建工具 Apache Maven 3.9.9

开发步骤及源码

1> 创建Maven工程,添加依赖。

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.jiyongliang</groupId>
        <artifactId>springboot3-web</artifactId>
        <version>0.0.1</version>
    </parent>
    <artifactId>springboot3-web-media</artifactId>

    <properties>
        <java.version>21</java.version>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-boot.version>3.3.3</spring-boot.version>
        <lombok.version>1.18.34</lombok.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

2> 定义SpringBoot应用启动类。

复制代码
package com.jiyongliang.springboot;

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

@SpringBootApplication
public class SpringBoot3WebMediaApplication {

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

3> 创建测试用图片资源,目录:src/main/resources/images

4> 创建返回图片的 Controller。

复制代码
package com.jiyongliang.springboot.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;

@RestController
@RequestMapping("/image")
@Slf4j
public class ImageController {

    /**
     * http://localhost:8080/image/jpg/WARCRAFT.jpg
     */
    @GetMapping("/jpg/{imageName}")
    public ResponseEntity<FileSystemResource> jpg(@PathVariable(name = "imageName") String imageName) {
        return getImageAsResource(imageName, MediaType.IMAGE_JPEG);
    }

    /**
     * http://localhost:8080/image/png/wukong.png
     */
    @GetMapping("/png/{imageName}")
    public ResponseEntity<byte[]> png(@PathVariable(name = "imageName") String imageName) {
        return getImageAsByteArray(imageName, MediaType.IMAGE_PNG);
    }

    private ResponseEntity<FileSystemResource> getImageAsResource(String imageName, MediaType mediaType) {
        try {
            File file = ResourceUtils.getFile("classpath:images/" + imageName);
            FileSystemResource resource = new FileSystemResource(file);
            return ResponseEntity.ok()
                    .contentLength(file.length())
                    .contentType(mediaType)
                    .body(resource);
        } catch (FileNotFoundException e) {
            log.error("File[{}] is not existed", imageName);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }
    }

    private ResponseEntity<byte[]> getImageAsByteArray(String imageName, MediaType mediaType) {
        try {
            File file = ResourceUtils.getFile("classpath:images/" + imageName);
            byte[] imageBytes = Files.readAllBytes(file.toPath());
            return ResponseEntity.ok()
                    .contentLength(imageBytes.length)
                    .contentType(mediaType)
                    .body(imageBytes);
        } catch (FileNotFoundException e) {
            log.error("File[{}] is not existed", imageName);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        } catch (IOException e) {
            log.error("Unexpected server error: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}

5> 启动应用,使用浏览器测试。

工程目录结构

相关推荐
叫我阿柒啊1 小时前
从Java全栈到云原生:一场技术深度对话
java·spring boot·docker·微服务·typescript·消息队列·vue3
计算机毕设定制辅导-无忧学长2 小时前
MQTT 与 Java 框架集成:Spring Boot 实战(一)
java·网络·spring boot
叫我阿柒啊2 小时前
从Java全栈到Vue3实战:一次真实面试的深度复盘
java·spring boot·微服务·vue3·响应式编程·前后端分离·restful api
泉城老铁2 小时前
Spring Boot中实现多线程分片下载
java·spring boot·后端
泉城老铁2 小时前
Spring Boot中实现多文件打包下载
spring boot·后端·架构
泉城老铁2 小时前
Spring Boot中实现大文件分片下载和断点续传功能
java·spring boot·后端
友莘居士2 小时前
长流程、复杂业务流程分布式事务管理实战
spring boot·rocketmq·saga·复杂流程分布式事务·长流程
百思可瑞教育2 小时前
Spring Boot 参数校验全攻略:从基础到进阶
运维·服务器·spring boot·后端·百思可瑞教育·北京百思教育
小蒜学长3 小时前
spring boot驴友结伴游网站的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端
一个松11 小时前
【无标题】
spring boot