Docker部署Spring Boot后如何访问上传的静态图片文件?
问题分析与解决方案
核心问题
- 资源映射路径不匹配:你的资源配置指向容器根目录
file:/,但实际图片存储在容器的/opt/app目录下(Dockerfile设置了WORKDIR /opt/app,new File(...)默认在当前工作目录创建文件)。 - 返回链接错误:控制器返回的是本地文件URI,而非可访问的HTTP接口链接。
- 文件操作不规范:手动关闭流存在资源泄漏风险,且文件名处理逻辑有隐患。
分步修复
1. 修改图片存储逻辑,规范目录与文件名
修改ImageController,将图片统一存储到专门的目录,并返回正确的访问链接:
@Slf4j @RestController @RequestMapping(value = "/api/v1/image") public class ImageController { // 固定容器内的图片存储目录 private static final String UPLOAD_DIR = "/opt/app/upload/"; public ImageController() { // 初始化存储目录,不存在则创建 File dir = new File(UPLOAD_DIR); if (!dir.exists()) { dir.mkdirs(); } } @PostMapping public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile multipartFile) throws IOException { // 安全获取文件扩展名,避免原文件名含多个点的情况 String extension = StringUtils.getFilenameExtension(multipartFile.getOriginalFilename()); String fileName = UUID.randomUUID().toString() + "." + extension; File destFile = new File(UPLOAD_DIR + fileName); // 使用try-with-resources自动关闭流,避免资源泄漏 try (FileOutputStream fos = new FileOutputStream(destFile)) { fos.write(multipartFile.getBytes()); } // 返回可直接访问的HTTP链接 String accessUrl = "/img/" + fileName; return ResponseEntity.ok(accessUrl); } }
需导入org.springframework.util.StringUtils工具类
2. 修正资源映射配置
修改CustomWebMvcConfig,将/img/**指向实际的存储目录:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CustomWebMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/img/**") // 指向实际存储目录,末尾斜杠必须保留 .addResourceLocations("file:/opt/app/upload/"); } }
3. 完善Dockerfile的目录权限
在Dockerfile中添加创建存储目录并设置权限的步骤,避免运行时权限问题:
FROM maven:3.6.0-jdk-13-alpine AS maven WORKDIR /app COPY ./src ./src COPY pom.xml . RUN mvn package FROM adoptopenjdk/openjdk11:x86_64-ubuntu-jre-11.0.18_10 WORKDIR /opt/app # 创建上传目录并设置可读可写权限 RUN mkdir -p /opt/app/upload && chmod 755 /opt/app/upload COPY --from=maven ./app/target/spring.jar . EXPOSE 8080 ENTRYPOINT ["java","-jar", "spring.jar"]
验证步骤
- 重新构建镜像并启动容器:
docker build -t spring-image-app . docker run -d -p 8080:8080 spring-image-app
- 发送POST请求到
http://localhost:8080/api/v1/image,携带file参数上传图片。 - 使用接口返回的
/img/xxx-xxx-xxx.jpg路径,访问http://localhost:8080/img/xxx-xxx-xxx.jpg即可查看图片。
额外建议
- 生产环境不要将图片存储在容器本地,建议使用云存储(如OSS)或独立文件服务器,避免容器销毁时丢失文件。
- 若需持久化存储,可在运行容器时挂载外部目录:
docker run -d -p 8080:8080 -v /本地路径:/opt/app/upload spring-image-app
内容的提问来源于stack exchange,提问作者Yuri
相关产品推荐
相关产品推荐

