SpringMVC之文件的上传

2023-12-22 16:58:32

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
SpringMVC之文件的上传


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

在当今数字化的时代,文件上传已经成为了许多应用程序中常见的功能之一。无论是在社交媒体、电子商务还是企业内部的文件管理系统中,用户都需要能够方便地上传文件。而作为一款优秀的 Java Web 框架,Spring MVC 为开发者提供了一种简单而强大的方式来实现文件上传功能。
通过 Spring MVC,开发者可以轻松地接收用户上传的文件,并将其保存到指定的位置。同时,Spring MVC 还提供了丰富的注解和拦截器,使得开发者可以更方便地处理文件上传的逻辑,以及对上传的文件进行校验和过滤。
在本博客中,我们将深入探讨 Spring MVC 中文件上传的相关概念和技术。我们将从基础知识开始,逐步介绍如何创建文件上传表单、处理上传请求以及保存上传的文件。此外,我们还将讨论一些高级主题,如文件类型校验、文件大小限制以及文件上传的安全性等。
无论你是 Spring MVC 的新手,还是有一定经验的开发者,本博客都将为你提供有价值的信息和实用的技巧。让我们一起开启 Spring MVC 文件上传的探索之旅吧!


提示:以下是本篇文章正文内容,下面案例可供参考

一、文件上传

原生方式上传

1.前端页面添加表单,设置enctype属性为multipart/form-data,并添加一个元素用于选择文件,以及一个提交按钮。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>上传</title>
  </head>
  <body>
    <h3>文件上传</h3>
     <%-- 表单的提交方式必须是post --%>
     <%-- enctype属性为multipart/form-data,意思是不对表单数据进行编码 --%>
    <form action="/fileUpload" method="post" enctype="multipart/form-data">
       <%-- 文件选择控件,类型是file,必须要有name属性--%>
       选择文件:<input type="file" name="upload"/>
      <input type="submit" value="上传"/>
    </form>
  </body>
</html>

2.引入依赖

<!-- 文件上传 -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.3.1</version>
</dependency>
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.4</version>
</dependency>

3.接收请求体数据,并写入磁盘

@RequestMapping("/fileUpload")
public String upload(HttpServletRequest request) throws Exception {
  // 创建文件夹,存放上传文件
  // 1.设置上传文件夹的真实路径
  String realPath = request.getSession().getServletContext().getRealPath("/upload");
  // 2.判断该目录是否存在,如果不存在,创建该目录
  File file = new File(realPath);
  if(!file.exists()){
    file.mkdirs();
   }
  // 分析请求体,找到上传文件数据
  // 1.创建磁盘文件工厂
  DiskFileItemFactory factory = new DiskFileItemFactory();
  // 2.创建上传数据分析器对象
  ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
  // 3.利用分析器对象解析请求体,返回所有数据项
  List<FileItem> fileItems = servletFileUpload.parseRequest(request);
  // 4.遍历所有数据,找到文件项(非表单项)
  for (FileItem fileItem:fileItems){
    if(!fileItem.isFormField()){
      // 将文件数据写入文件夹
      // 1.获取文件名
      String name = fileItem.getName();
      // 2.将文件写入磁盘
      fileItem.write(new File(file,name));
      // 3.删除内存中的临时文件
      fileItem.delete();
     }
   }
  return "index";
}

SpringMVC方式上传

SpringMVC文件解析器对象,可以直接将请求体中的文件数据转为MuiltipartFile对象
1.在SpringMVC核心配置文件配置文件解析器

<!-- 文件解析器对象,id名称必须是multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <!-- 支持一次上传文件的总容量。单位:字节 100M = 100*1024*1024-->
  <property name="maxUploadSize" value="104857600"/>
  <!-- 文件名的编码方式-->
  <property name="defaultEncoding" value="utf-8"/>
</bean>

2.前端文件上传代码

<!DOCTYPE html>
<html>
<head>
    <title>File Upload Example</title>
</head>
<body>
    <h1>文件上传</h1>
    <form action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file" />
        <input type="submit" value="上传" />
    </form>
</body>
</html>

3.后端代码实现文件上传
注:记得引入前面的依赖

// MultipartFile参数名必须和HTML文件空间的name属性一致
@RequestMapping("/upload")
public String upload(MultipartFile file,HttpServletRequest request) throws IOException {
  // 创建文件夹,存放上传文件
  String realPath = request.getSession().getServletContext().getRealPath("/upload");//获取当前 Web 应用的实际路径下的 /upload 文件夹的路径。
  File dir = new File(realPath);
  if(!dir.exists()){
    dir.mkdirs();
   }
  // 将上传的数据写到文件夹的文件中
  // 1.拿到上传的文件名
  String filename = file.getOriginalFilename();
  filename = UUID.randomUUID()+"_"+filename;
  // 2.创建空文件
  File newFile = new File(dir,filename);
  // 3.将数据写入空文件中
  file.transferTo(newFile);
  return "index";
}

注意注意:
MultipartFile参数名必须和HTML文件空间的name属性一致
MultipartFile参数名必须和HTML文件空间的name属性一致
MultipartFile参数名必须和HTML文件空间的name属性一致
重要的事情说3遍
此外,还需要注意文件上传的大小限制、文件路径的安全性等方面的问题,以确保文件上传功能的可靠性和安全性。

多文件上传

1.在SpringMVC核心配置文件配置文件解析器

<!-- 文件解析器对象,id名称必须是multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <!-- 支持一次上传文件的总容量。单位:字节 100M = 100*1024*1024-->
  <property name="maxUploadSize" value="104857600"/>
  <!-- 文件名的编码方式-->
  <property name="defaultEncoding" value="utf-8"/>
</bean>

2.前端文件上传代码

<!DOCTYPE html>
<html>
<head>
    <title>文件上传</title>
</head>
<body>
    <h1>文件上传</h1>

    <!-- 文件上传表单 -->
    <form action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file" multiple>
         <input type="file" name="file" multiple>
        <input type="submit" value="上传">
    </form>
</body>
</html>

3.后端代码实现
注:记得引入前面的依赖

 // 上传多个文件的处理方法
    @RequestMapping(value = "/uploadMultiple", method = RequestMethod.POST)
    public String handleUploadMultipleFiles(@RequestParam("file") List<MultipartFile> files) {
        // 创建一个 List 来存储上传的文件名
        List<String> fileNames = new ArrayList<>();
        if (files != null) {
            for (MultipartFile file : files) {
                // 获取上传的文件名
                String fileName = file.getOriginalFilename();
                // 在本地创建文件
                File localFile = new File(fileName);
                // 将上传的文件内容写入本地文件
                try {
                    file.transferTo(localFile);
                    System.out.println("文件 " + fileName + " 上传成功!");
                    fileNames.add(fileName);
                } catch (Exception e) {
                    System.out.println("文件上传失败!");
                }
            }
        }
        // 输出上传的文件名列表
        System.out.println("上传的文件名列表:" + fileNames);
        return "上传成功";
    }

多文件上传和单文件上传相传不大,只是参数不一样,任可参考单文件上传

异步上传

什么是异步上传

HTTP 异步上传是一种在 Web 应用程序中常见的场景,它允许用户上传文件到服务器而无需等待整个上传过程完成。以下是一个通俗易懂的解释:
想象一下,你有一个网站,用户可以在该网站上上传他们的照片或其他文件。当用户选择要上传的文件并点击“上传”按钮时,传统的上传方式会立即将文件发送到服务器,并在上传完成之前阻止用户进行其他操作。
但是,在异步上传的场景中,事情会有所不同。当用户点击“上传”按钮时,你的网站会将文件的一部分数据发送到服务器,并立即向用户显示一个进度条或其他反馈,让他们知道上传正在进行中。然后,用户可以继续在网站上进行其他操作,而上传将在后台继续进行。
在后台,上传进程会将文件的剩余部分逐渐发送到服务器,而不会阻塞用户的操作。这意味着用户可以在上传进行的同时浏览其他页面、填写表单或执行其他任务。当上传完成时,服务器会通知用户,并可以在网站上显示上传成功的消息。
这种异步上传的方式可以提供更好的用户体验,因为用户无需等待整个上传过程完成,他们可以继续与网站进行交互,而上传将在后台自动进行。

实现步骤

1.前端文件上传代码,引入jQuery和jQuery表单上传工具jquery.form.js

<!DOCTYPE html>
<html>
<head>
    <title>文件上传</title>
</head>
<body>
    <h1>文件上传</h1>

    <!-- 文件上传表单 -->
    <form action="/upload" method="post" enctype="multipart/form-data" id="a">
        <input type="file" name="file" multiple>
         <input type="file" name="file" multiple>
        <input type="button" value="上传" id="btn">
    </form>
    <script>
  $(function () {
    $("#btn").click(function () {
      // 异步提交表单
      $("#a").ajaxSubmit({
        url:"/fileUpload4",
        type:"post",
        success:function (data) {
          $("#img").attr("src",data);
         }
       })
     })
   })
</script>
</body>
</html>

2.后端代码

@RequestMapping("/fileUpload4")
//不进行页面跳转
@ResponseBody
public String upload3(HttpServletRequest request, MultipartFile file) throws Exception {
  // 创建文件夹,存放上传文件。
  String realPath = request.getSession().getServletContext().getRealPath("/upload");
  File dir = new File(realPath);
  if (!dir.exists()){
    dir.mkdirs();
   }
  // 拿到上传文件名
  String filename = file.getOriginalFilename();
  filename = UUID.randomUUID()+"_"+filename;
  // 创建空文件
  File newFile = new File(dir, filename);
  // 将上传的文件写到空文件中
  file.transferTo(newFile);
  // 返回文件的路径
  return "/upload/"+filename;
}

跨服务器上传

由于文件占据磁盘空间较大,在实际开发中往往会将文件上传到其他服务器中,此时需要使用跨服务器上传文件。假设现在我们有两台服务器,一台服务器是上传文件的服务器,端口是8080,另一台是图片服务器,用于储存用户上传的文件,端口9090
1.修改tomcat的conf/web.xml文件,支持跨服上传

<servlet>  
  <init-param>    
    <param-name>readonly</param-name>   
    <param-value>false</param-value>  
  </init-param>
</servlet>

2.编写前端代码,用异步提交方式提交,这里参考前面的代码,不予展示
3.添加跨服上传依赖

<!-- 跨服上传 -->
<dependency>
  <groupId>com.sun.jersey</groupId>
  <artifactId>jersey-core</artifactId>
  <version>1.18.1</version>
</dependency>
<dependency>
  <groupId>com.sun.jersey</groupId>
  <artifactId>jersey-client</artifactId>
  <version>1.18.1</version>
</dependency>

4.后端代码实现

@RequestMapping("/fileUpload5")
@ResponseBody
public String upload4(HttpServletRequest request, MultipartFile file) throws Exception {
  // 设置跨服上传的服务器路径
  String path = "http://localhost:9090/upload/";
  // 获取上传的文件名
  String filename = file.getOriginalFilename();
  filename = UUID.randomUUID()+"_"+filename;
  // 跨服上传:
  // 1.创建客户端对象
  Client client = Client.create();
  // 2.使用客户端对象连接图片服务器
  WebResource resource = client.resource(path + filename);
  //3.传输数据
  resource.put(file.getBytes());
  return path+filename;
}


总结

提示:这里对文章进行总结:

总的来说,Spring MVC 为文件上传提供了一套简洁而强大的解决方案。通过本博客的学习,你应该对 Spring MVC 文件上传有了更深入的理解,并能够在实际项目中应用这些知识。希望本博客对你有所帮助,如有任何问题,欢迎留言讨论!

文章来源:https://blog.csdn.net/liubopro666/article/details/135152503
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。