25.后端接收前端传来的文件

后端处理前端传来的文件

1.在 Spring MVC 中,这套流程非常标准化。你需要做的是:接收 MultipartFile、生成唯一文件名、保存到服务器磁盘、最后返回文件的访问 URL。

2.首先要设定一个文件保存的基本路径

// 设定一个保存文件的基础路径(例如:D:/uploads/ 或 /var/www/uploads/)
    private final String uploadPath = "G:/my_uploads/";

3.接收 MultipartFile 以及一些其他的普通参数(均可以通过FormData.append添加)

  • 前端

    // 前端FormData:
    formData.append('avatar', avatarFile); // 单个文件
    formData.append('attachments', file1); // 附件1
    formData.append('attachments', file2); // 附件2
    formData.append('userId', 123);
    
  • 后端

    // 后端接收:
    @PostMapping("/upload")
    public Map<String, Object> upload(
        @RequestParam("userId") Integer userId,
        @RequestParam("avatar") MultipartFile avatar, // 单个文件
        @RequestParam("attachments") List<MultipartFile> attachments) { // 多个附件
      // 处理逻辑...
    }
    

    用hashMap返回信息给前端。

  • 对前端传输来的文件的处理

      // 1. 获取原始文件名
       String originalFilename = file.getOriginalFilename();
       // 2. 获取文件后缀 (例如: .jpg)
       String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    
       // 3. 生成“别名” (使用 UUID 防止文件名冲突)
       String newFileName = UUID.randomUUID().toString().replace("-", "") + suffix;
    
  • 保存文件在本地磁盘

    // 4. 保存到本地磁盘
              File dest = new File(uploadPath + newFileName);
              // 如果目录不存在则创建
              if (!dest.getParentFile().exists()) {
                  dest.getParentFile().mkdirs();
              }
              file.transferTo(dest); // 保存文件核心代码
    
              // 5. 构造返回给前端的链接
              // 假设你的后端运行在 8080 端口,且配置了静态资源映射
              String fileUrl = "http://localhost:8089/springmvc_redis_war/files/" + newFileName;
    
  • 用户怎样访问?
    通过别名映射,返回后端静态资源地址+生成的uuid别名

    String baseUrl = "http://localhost:8089/springmvc_redis_war/files/";
    //这里的uuid来自于数据库查询,如:青花瓷-----uuid1,青花瓷----uuid2   虽然有两个同名,但是他们属于不同的音乐信息,不同的人唱的
    String fileUrl = baseUrl + uuid;
    result.put("url", fileUrl); // 返回给前端的链接
    
    

4.有两个非常需要注意到的点

  • 注意!!!:前端不能直接通过文件路径(如 C:\uploads\123.jpg)访问本地电脑的文件。
    出于安全考虑,现代浏览器严禁网页代码直接访问用户的本地文件系统。
    如果你在 HTML 中写 <img src="C:/my_uploads/test.jpg">,浏览器会直接报错:"Not allowed to load local resource"。
    如果可以随便访问,那么任何恶意网站都能偷偷读取你电脑里的隐私文件(如身份证照片、银行账单)。

    基于此考虑,需要把后端服务器变成一个静态资源服务器。

    当你访问 http://localhost:8089/springmvc_redis_war/files/image.jpg 时:

    1. 浏览器向后端(Spring MVC)发起一个标准的 HTTP GET 请求。
    2. Spring MVC 接收到请求,根据你配置的 addResourceHandlers,去硬盘的物理路径找到那个文件。如:
    <mvc:resources mapping="/files/**" location="file:G:/my_uploads/" />
    在这里会爆红,但是本身没有错
    

    image

    我们可以设置一下编译器,让他不验证这类语法
    image

    image

    1. 后端把文件内容通过网络流返回给浏览器。
    2. 浏览器接收到数据,展示图片。
  • 在 Spring MVC 中,处理文件上传最常见的 500 错误原因有两个:

    • 原因 1:缺少 Commons-FileUpload 依赖

      传统的 Spring MVC(非 Spring Boot)不自带处理 multipart/form-data 的功能,必须依赖外部 Jar 包。如果你没加这两个依赖,Spring 会因为找不到解析器而崩溃。

      <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.4</version>
      </dependency>
      <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.11.0</version>
      </dependency>
      
    • 原因 2:XML 中没有配置 MultipartResolver
      就算有了依赖,你还得在 XML 里告诉 Spring:“请使用 CommonsFileUpload 来帮我解析前端传来的文件”。

      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <property name="maxUploadSize" value="10485760" />
          <property name="defaultEncoding" value="UTF-8" />
      </bean>
      

小细节:bean id="multipartResolver"是固定只能这个名.
Spring 的内部机制是“约定优于配置”。当请求到达时,Spring 会尝试调用: context.getBean("multipartResolver", MultipartResolver.class)
如果你没起名:Spring 找不到这个 Bean,会认为你不需要文件上传功能。
如果你起错名(比如 id="myResolver"):Spring 依然找不到名为 multipartResolver 的 Bean,导致后端接收到的 MultipartFile 对象永远是 null 或者报错。

posted @ 2026-01-03 16:16  那就改变世界吧  阅读(20)  评论(0)    收藏  举报