水泥封心 發表於 2026-1-6 09:59:05

docker部署springboot项目文件上传路径过程

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">一、问题</a></li><li><a href="#_label1">二、环境</a></li><li><a href="#_label2">三、创建springboot项目</a></li><li><a href="#_label3">四、docker部署项目</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_0">(1)构建镜像</a></li><li><a href="#_lab2_3_1">(2)启动容器</a></li><ul class="third_class_ul"><li><a href="#_label3_3_1_0">(1)不挂载文件启动容器</a></li><li><a href="#_label3_3_1_1">(2)挂载文件启动容器</a></li></ul></ul><li><a href="#_label4">三、补充</a></li><ul class="second_class_ul"></ul><li><a href="#_label5">四、总结</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>一、问题</h2>
<p>解决通过docker部署springboot项目,文件上传的路径该怎么设置?</p>
<p>用docker部署后,在服务器上面怎么看到自己上传的文件,文件需不需要挂载等问题,下面直接使用springboot+docker简单搭建一个文件服务器</p>
<p class="maodian"><a name="_label1"></a></p><h2>二、环境</h2>
<p>以下是本人此次搭建的环境</p>
<ul><li>部署方式:docker</li><li>服务器:linux服务器</li><li>服务器操作系统:CentOS 8.2</li><li>jdk:1.8</li></ul>
<p class="maodian"><a name="_label2"></a></p><h2>三、创建springboot项目</h2>
<p>创建springboot项目upload-demo,先在本地进行测试,确保本地的项目可以进行文件上传和下载</p>
<p><strong>pom</strong></p>
<div class="jb51code"><pre class="brush:xml;">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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 https://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
      &lt;version&gt;2.7.0&lt;/version&gt;
      &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;
    &lt;/parent&gt;
    &lt;groupId&gt;com.zqcn&lt;/groupId&gt;
    &lt;artifactId&gt;upload_demo&lt;/artifactId&gt;
    &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
    &lt;name&gt;upload_demo&lt;/name&gt;
    &lt;description&gt;Demo project for Spring Boot&lt;/description&gt;
    &lt;properties&gt;
      &lt;java.version&gt;1.8&lt;/java.version&gt;
    &lt;/properties&gt;
    &lt;dependencies&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;/artifactId&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
      &lt;/dependency&gt;

      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
            &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;

    &lt;build&gt;
      &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
            &lt;/plugin&gt;
      &lt;/plugins&gt;
    &lt;/build&gt;

&lt;/project&gt;

</pre></div>
<p>application.yml</p>
<div class="jb51code"><pre class="brush:yaml;">upload:
#部署服务器时的服务上文件存放地址
#path: /upload-demo/upload

# 本地的文件存放地址
path: D:\zqcn\data\upload-demo\upload

server:
port: 8082
</pre></div>
<p>为了方便直观的看到效果,这里就简单写了两个html页面进行测试</p>
<p><strong>upload-page.html(文件上传页面)</strong></p>
<div class="jb51code"><pre class="brush:xhtml;">&lt;!DOCTYPE html&gt;
&lt;html lang="en" xmlns:th="http://www.thymeleaf.org"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;File Upload&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;form enctype="multipart/form-data" method="post" action="/file/receive"&gt;
    &lt;div&gt;
      File Choose:
      &lt;input type="file" name="file"&gt;&lt;/div&gt;
    &lt;div&gt;
      &lt;input type="submit" value="Submit"/&gt;
    &lt;/div&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre></div>
<p><strong>download-page.html(文件下载页面)</strong></p>
<div class="jb51code"><pre class="brush:xhtml;">&lt;!DOCTYPE html&gt;
&lt;html lang="en" xmlns:th="http://www.thymeleaf.org"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;File Upload&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;form action="/file/fetch" method="post"&gt;
    下载文件名:&lt;input type="text" name="fileName" maxlength="500" style="width:400px;"&gt;


    &lt;input type="submit" value="提交"&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre></div>
<p>最后编写对应的controller即可</p>
<p><strong>FileController</strong></p>
<div class="jb51code"><pre class="brush:bash;">package com.zqcn.upload_demo.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
* @ClassName : FileController
* @Description :
* @Author : CJH
* @Date: 2022-06-15 09:37
*/
@Controller
@RequestMapping("/file")
public class FileController {

    @Value("${upload.path}")
    private String uploadPath;


    /**
   * 文件上传页面
   * @param request
   * @return
   */
    @RequestMapping("/upload")
    public String uploadPage(HttpServletRequest request){
      return "upload-page";
    }


    /**
   * 文件下载页面
   * @param request
   * @return
   */
    @RequestMapping("/download")
    public String downloadPage(HttpServletRequest request){
      return "download-page";
    }


    /**
   * 文件上传接口
   * @param file
   * @param request
   * @return
   * @throws Exception
   */
    @ResponseBody
    @RequestMapping(value="/receive", method = RequestMethod.POST)
    public Map receiveFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception{
      if(file.isEmpty()){
            return new HashMap&lt;String,Object&gt;(){{
                put("code",500);
                put("msg","没有选中任何文件");
                put("status",false);
                put("data",null);
            }};
      }


      File uploadFileSaveDir = new File(uploadPath);
      System.out.println("上传文件的存放目录:"+uploadFileSaveDir.getAbsolutePath());
      if(!uploadFileSaveDir.exists()){
            // 递归生成文件夹
            uploadFileSaveDir.mkdirs();
      }

      // 拿到文件名
      String filename = file.getOriginalFilename();
      // 构建真实的文件路径
      File uploadFile = new File(uploadFileSaveDir.getAbsolutePath() + File.separator + filename);
      System.out.println("文件上传到:" + uploadFile.getAbsolutePath());
      //文件写到服务器,
      file.transferTo(uploadFile);



      return new HashMap&lt;String,Object&gt;(){{
            put("code",200);
            put("msg","文件上传成功");
            put("status",true);
            put("data",null);
      }};

    }


    /**
   * 文件下载接口
   * @param fileName
   * @param response
   * @return
   * @throws Exception
   */
    @ResponseBody
    @RequestMapping(value = "/fetch", method = RequestMethod.POST)
    public Map fileDownload(@RequestParam() String fileName, HttpServletResponse response)throws Exception{
      File downloadFile = new File(uploadPath + File.separator + fileName);
      System.out.println("下载文件的完整路径:"+downloadFile.getAbsolutePath());
      if(!downloadFile.exists()){
            System.out.println("要下载的文件不存在:"+downloadFile.getAbsolutePath());
            return new HashMap&lt;String,Object&gt;(){{
                put("code",500);
                put("msg","文件不存在,下载失败");
                put("status",false);
                put("data",null);
            }};
      }else {
            //第二读取文件
            InputStream in = new FileInputStream(downloadFile);
            //设置响应头,对文件进行url编码
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename="+fileName);
            response.setContentLength(in.available());

            //第三步:读文件写入http响应
            OutputStream out = response.getOutputStream();
            byte[] b = new byte;
            int len = 0;
            while((len = in.read(b))!=-1){
                out.write(b, 0, len);
            }
            out.flush();
            out.close();
            in.close();
            return new HashMap&lt;String,Object&gt;(){{
                put("code",200);
                put("msg","文件下载成功");
                put("status",true);
                put("data",null);
            }};
      }
    }
}

</pre></div>
<p>启动项目,先用postman测试一下上传接口</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502481.png" /></p>
<p>再测试一下下载接口</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502568.png" /></p>
<p>接口测试没问题,下面可以测一下那两个页面</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502431.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502566.png" /></p>
<p>都是正常的,本地项目创建成功</p>
<p class="maodian"><a name="_label3"></a></p><h2>四、docker部署项目</h2>
<p class="maodian"><a name="_lab2_3_0"></a></p><h3>(1)构建镜像</h3>
<p>关于linux服务器和docker的基础知识这里就不赘述了,自行百度即可,下面直接进入部署流程,先把项目的文件上传路径改成部署环境的上传地址</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502573.png" /></p>
<p>再本地进行jar打包</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502534.png" /></p>
<p>创建Dockerfile文件</p>
<div class="jb51code"><pre class="brush:bash;">FROMjava
VOLUME/tmp
ADD upload_demo.jar upload_demo.jar
EXPOSE 8082
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/upload_demo.jar"]

</pre></div>
<ul><li>FROM java:表示安装的java镜像</li><li>VOLUME /tmp:创建/tmp目录并持久化到Docker数据文件夹</li><li>ADD upload_demo.jar upload_demo.jar:将生成的jar包(第一个)复制并重命名到upload_demo.jar(第二个)</li><li>EXPOSE 8082:对外暴露的接口,也是访问的接口,接口的端口号需要根据springboot项目配置的端口号来设置</li><li>ENTRYPOINT:固定写法,用来运行jar包,相当于java -jar xxx.jar一样</li></ul>
<p>最后将jar和Dockerfile通过xftp一起上传到服务器上面,最好找个文件夹统一放在一起,例如</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502569.png" /></p>
<p>再通过xshell进入jar和Dockerfile所在的目录,并且输入构建镜像的命令</p>
<div class="jb51code"><pre class="brush:bash;">docker build -t upload-demo .
</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502571.png" /></p>
<p>构建成功后,先随便创建</p>
<p class="maodian"><a name="_lab2_3_1"></a></p><h3>(2)启动容器</h3>
<p>为了更清楚的理解docker部署的项目文件上传路径,这里分两种方式启动容器,一种不挂载文件,一种挂载文件,两种方式,简单分析一下文件的上传路径</p>
<p class="maodian"><a name="_label3_3_1_0"></a></p><h4>(1)不挂载文件启动容器</h4>
<p>命令如下:</p>
<div class="jb51code"><pre class="brush:bash;">sudo docker run -d --name upload-demo01 -p 8082:8082upload-demo
</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502566.png" /></p>
<p>容器启动成功后,用postman进行文件上传测试,上传了1.jpeg文件</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502557.png" /></p>
<p>上传也是成功了,那么怎么看到上传的图片呢,还有就springboot项目配置的文件上传地址体现在哪里,要想知道这些答案,就需要进入容器内部看了,命令</p>
<div class="jb51code"><pre class="brush:bash;">docker exec -it upload-demo01 /bin/bash
</pre></div>
<p>进入里面后查看当前目录下的文件,就会发现upload-demo,这个就springboot配置的上传地址</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502513.png" /></p>
<p>再进入upload-demo文件里面看看</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502593.png" /></p>
<p>就会发现里面有一个文件夹upload,再深入里面看看,就会发现里面有一张图片1.jpeg,就是我们上传的图片了</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502561.png" /></p>
<p>总结一下容器里面的路径地址就是:/upload-demo/upload,这个路径就是springboot配置的文件上传地址</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502583.png" /></p>
<p>至此为止,整体容器启动后,文件上传和下载都是正常的,唯一不足的就是,如果要看这个图片上传在哪里,就需要进入容器里面看,下面推荐第二种方式,启动容器后,并且把容器里面的图片挂载出来</p>
<p class="maodian"><a name="_label3_3_1_1"></a></p><h4>(2)挂载文件启动容器</h4>
<p>先在服务器上创建一个目录,用于存放挂载出来的图片,本人的路径是/home/cainiao/upload-demo/upload</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502556.png" /></p>
<p>下面执行以下命令启动容器:</p>
<div class="jb51code"><pre class="brush:bash;"> sudo docker run -d --name upload-demo02 -p 8083:8082-v /home/cainiao/upload-demo/upload:/upload-demo/upload   upload-demo
</pre></div>
<p>注意:</p>
<ul><li>/home/cainiao/upload-demo/upload:是你要挂载到容器外面的服务器图片路径</li><li>/upload-demo/upload:是容器里面图片地址</li></ul>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502548.png" /></p>
<p>容器启动成功,现在用postman进行接口上传测试,文件2.jpeg上传成功</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502578.png" /></p>
<p>现在去服务器上面的/home/cainiao/upload-demo/upload里面,刷新一下,看一下发现图片已经挂载出来了</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502521.png" /></p>
<p>现在试一下图片下载</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010609502597.jpg" /></p>
<p>可以看到图片,经过测试,图片可以完成下载</p>
<p class="maodian"><a name="_label4"></a></p><h2>三、补充</h2>
<p>正常部署的话,建议采用第二种采用挂载文件的形式进行启动</p>
<p class="maodian"><a name="_label5"></a></p><h2>四、总结</h2>
<p>以上为个人经验,希望能给大家一个参考,也希望大家多多支持琼殿技术社区。</p>
頁: [1]
查看完整版本: docker部署springboot项目文件上传路径过程