当前位置: 首页 > news >正文

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

在这篇文章中,我们将介绍如何使用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控制器,用于从指定路径加载图片并将其作为资源返回给客户端。它包括必要的安全措施来防止潜在的路径遍历攻击,并设置了缓存控制头以提高性能。希望这段代码能为您提供构建自己的图片服务的帮助!

http://www.dtcms.com/a/339358.html

相关文章:

  • WSL2环境下的Claude Code与lanyuncodingui安装与配置
  • 差速转向机器人研发:创新驱动的未来移动技术探索
  • 子网掩码(拓)
  • 汇编语言学习2---GNU Debugger (GDB)
  • bypass webshell--Trait
  • canopen 初体验
  • 【qml-4】qml与c++交互(类型多例)
  • 配置nginx以支持http3
  • rabbitmq发送的延迟消息时间过长就立即消费了
  • Maven的三种项目打包方式——pom,jar,war的区别
  • 微算法科技(NASDAQ: MLGO)研究利用PBFT中的动态视图变换机制,实现区块链系统高效运转
  • 股指本周想法
  • 区块链 + 域名Web3时代域名投资的新风口(下)
  • 使用 Docker 安装长安链管理平台 + 部署长安链
  • DL00291-联邦学习以去中心化锂离子电池健康预测模型完整实现
  • Transformer实战(13)——微调Transformer语言模型用于文本分类
  • 操作系统:多线程、进程管理、内存分配、任务调度等
  • Gemini CLI 详细操作手册
  • ECC升级S4,AVL自定义GUI 状态无法显示全选和取消全选按钮
  • Matplotlib数据可视化实战:Matplotlib基础与实践-快速上手数据可视化
  • 学习嵌入式的第二十一天——数据结构——链表
  • 08.19总结
  • 豆包1.5轻量版 vs Gemini 2.5闪存版:生成5000字深度文章,哪个模型更合适?
  • 玳瑁的嵌入式日记D20-08019(数据结构)
  • audio接口的技术发展
  • Java技术总监的成长之路(技术干货分享)
  • 昆仑万维SkyWork AI技术发布周:多模态模型的全面突破
  • 记一次 .NET 某自动化智能制造软件 卡死分析
  • 一条 SQL 语句在 MySQL中的执行过程。
  • Python网络爬虫全栈教程 – 从基础到实战