Spring Boot应用实现图片资源服务的方法

 更新时间:2025年08月20日 11:09:15   作者:QingyunChen  
本文介绍如何使用SpringBoot创建REST API提供静态图片服务,涵盖路径安全检查、文件存在性验证及缓存控制功能,包含Maven依赖配置和代码注释,帮助开发者实现安全高效的图片资源访问,感兴趣的朋友跟随小编一起看看吧

在这篇文章中,我们将介绍如何使用Spring Boot创建一个REST API来提供服务器上的静态图片资源。该API包括路径安全检查、文件存在性验证以及缓存控制等功能,并且代码包含详细的注释以帮助理解。

Maven依赖

首先,在您的pom.xml文件中添加以下依赖项:

<dependencies>
    <!-- Spring Boot Starter Web for building web applications -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Lombok to reduce boilerplate code -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <scope>provided</scope>
    </dependency>
    <!-- For logging -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
    </dependency>
</dependencies>

确保您已经正确配置了Maven项目的其他部分,如<parent>标签和版本管理等。

Java代码

接下来是核心Java代码,位于package pub.qingyun.web;包下:

package pub.qingyun.web;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@RestController
@CrossOrigin
@Slf4j
public class ImageController {
    // 图片根目录
    private static final Path IMAGE_ROOT = Paths.get("F:", "Temp").toAbsolutePath().normalize();
    /**
     * 获取图片资源并返回给客户端
     *
     * @param imagePath 图片文件的相对路径参数
     * @return ResponseEntity<UrlResource> 包含图片资源的响应实体,包含适当的HTTP状态码和响应头
     */
    @GetMapping("/showImage")
    public ResponseEntity<UrlResource> getImage(@RequestParam String imagePath) {
        long start = System.currentTimeMillis();
        // 参数校验:检查图片路径是否为空
        if (imagePath == null || imagePath.trim().isEmpty()) {
            log.warn("Missing imagePath parameter");
            return ResponseEntity.badRequest().build();
        }
        // 路径安全检查:防止路径遍历攻击
        // 过滤非法字符,防止路径穿越
        if (imagePath.contains("..") || imagePath.contains("\\") || imagePath.startsWith("/")) {
            log.warn("Forbidden path access attempt: [PATH_REDACTED]");
            return ResponseEntity.status(403).build();
        }
        Path resolvedPath = IMAGE_ROOT.resolve(imagePath).normalize();
        if (!resolvedPath.startsWith(IMAGE_ROOT)) {
            log.warn("Forbidden path access attempt: [PATH_REDACTED]");
            return ResponseEntity.status(403).build();
        }
        // 文件存在性检查:验证文件是否存在且为常规文件
        if (!Files.exists(resolvedPath) || !Files.isRegularFile(resolvedPath)) {
            log.info("Image not found: [PATH_REDACTED]");
            return ResponseEntity.notFound().build();
        }
        // 缓存文件长度,避免重复调用
        long fileLength = resolvedPath.toFile().length();
        // 创建资源对象
        UrlResource resource;
        try {
            resource = new UrlResource(resolvedPath.toUri());
        } catch (MalformedURLException e) {
            log.error("Failed to create resource for: [PATH_REDACTED], Malformed URL", e);
            return ResponseEntity.status(500).build();
        } catch (Exception e) {
            log.error("Failed to create resource for: [PATH_REDACTED]", e);
            return ResponseEntity.status(500).build();
        }
        // 设置响应头信息
        HttpHeaders headers = new HttpHeaders();
        headers.setCacheControl("public, max-age=86400"); // 缓存 1 天
        headers.setExpires(System.currentTimeMillis() + 86400_000L); // 过期时间
        headers.setContentDispositionFormData("inline", resource.getFilename());
        log.info("getImage [PATH_REDACTED] ({} bytes) cost: {}ms", fileLength, (System.currentTimeMillis() - start));
        // 构建并返回成功响应
        return ResponseEntity.ok()
                .headers(headers)
                .contentType(MediaType.IMAGE_JPEG)
                .contentLength(fileLength)
                .body(resource);
    }
}

这个代码段展示了一个简单的Spring Boot REST控制器,用于从指定路径加载图片并将其作为资源返回给客户端。它包括必要的安全措施来防止潜在的路径遍历攻击,并设置了缓存控制头以提高性能。希望这段代码能为您提供构建自己的图片服务的帮助!

到此这篇关于Spring Boot应用实现图片资源服务的文章就介绍到这了,更多相关Spring Boot图片资源服务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Netty源码分析NioEventLoop线程的启动

    Netty源码分析NioEventLoop线程的启动

    这篇文章主要为大家介绍了Netty源码分析NioEventLoop线程的启动示例,有需要的朋友,可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • SpringBoot集成腾讯地图SDK的详细步骤

    SpringBoot集成腾讯地图SDK的详细步骤

    腾讯地图(Tencent Map)是腾讯公司推出的一款数字地图服务,提供丰富的地图展示、定位、搜索、导航等功能,本文给大家介绍了SpringBoot集成腾讯地图SDK的详细步骤,需要的朋友可以参考下
    2026-03-03
  • 基于Spring Boot DevTools实现开发过程优化

    基于Spring Boot DevTools实现开发过程优化

    这篇文章主要介绍了基于Spring Boot DevTools实现开发过程优化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Java多线程事务回滚@Transactional失效处理方案

    Java多线程事务回滚@Transactional失效处理方案

    这篇文章主要介绍了Java多线程事务回滚@Transactional失效处理方案,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-08-08
  • Spring BeanPostProcessor(后置处理器)的用法

    Spring BeanPostProcessor(后置处理器)的用法

    这篇文章主要介绍了Spring BeanPostProcessor(后置处理器)的用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java调用新浪api通过Ip查询地区

    Java调用新浪api通过Ip查询地区

    这篇文章主要介绍了Java调用新浪接口通过Ip查询地区,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • java.lang.Instrument 代理Agent使用详细介绍

    java.lang.Instrument 代理Agent使用详细介绍

    这篇文章主要介绍了java.lang.Instrument 代理Agent使用详细介绍的相关资料,附有实例代码,帮助大家学习参考,需要的朋友可以参考下
    2016-11-11
  • Java开发中StepBuilder模式详解

    Java开发中StepBuilder模式详解

    Step builder多阶段步骤构造器模式是一种对象创建软件设计模式,与传统构建器模式进行比较时,步骤构建器模式提供了一些简洁的好处,这篇文章主要介绍了Java开发中StepBuilder模式的相关资料,需要的朋友可以参考下
    2026-01-01
  • Java Maven高级之插件开发详解

    Java Maven高级之插件开发详解

    这篇文章主要介绍了Maven 插件开发的详细整理的相关资料,需要的朋友可以看下,希望能够给你带来帮助
    2021-09-09
  • Springboot异常日志输出方式

    Springboot异常日志输出方式

    这篇文章主要介绍了Springboot异常日志输出方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12

最新评论