Spring MVC多种情况下的文件上传

一、原生方式上传

上传是Web工程中很常见的功能,SpringMVC框架简化了文件上传的代码,我们首先使用JAVAEE原生方式上传文件来进行详细描述:

1.1 修改web.xml项目版本

这里我们创建新的SpringMVC模块,在web.xml中将项目从2.3改为3.1,即可默认开启el表达式,如下图:

1.2 上传JSP页面

那这里我们需要访问一个页面来进行文件下载

upload.jsp

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

1.3 引入文件上传依赖

接下来需要分析请求体中的文件项,并将数据写入磁盘,此时需要借助文件上传工具

    <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>

1.4 分析控制器执行流程

编写控制器接收上传请求,控制器进行三步操作:

  1. 创建文件夹,存放上传文件。
  2. 分析请求体,找到上传文件数据。
  3. 将文件数据写入文件夹。

完整文件上传控制器代码如下:

package com.example.controller;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.List;
import java.util.UUID;

@Controller
public class UploadController {

    @RequestMapping("/fileUpload")
    public String upload(HttpServletRequest request) throws Exception{
        // 创建文件夹,存放上传文件
        // 1.设置上传文件夹的真实路径
        String realpath = request.getSession().getServletContext().getRealPath("/upload");

        System.out.println(realpath);
        // 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);
        // 遍历所有数据,找到文件项(非表单项)
        for(FileItem fileItem:fileItems){
            if(!fileItem.isFormField()){
                // 将文件数据写进文件夹
                // 1.获取文件名
                String name = fileItem.getName();
                // 2.将文件写入磁盘
                fileItem.write(new File(file,name));
                System.out.println(file.getAbsoluteFile());
                // 3.删除内存中的临时文件
                fileItem.delete();
            }
        }
        return "index";
    }
}

文件成功下载后跳转到默认页面。 

1.5 测试结果

访问路径:http://localhost:8080/upload.jsp

点击选择文件,选择要上传的文件,然后点击上传。

OK,可以看得到webapp目录下面多了一个文件夹upload,并且里面有我们刚刚上传的文件。 可以看得出来用原生的方式来完成文件上传是比较麻烦的,接下来我们看一下用Spring MVC方式如何来进行文件上传

二、Spring MVC 方式上传

SpringMVC使用框架提供的文件解析器对象,可以直接将请求体中的文件数据转为MultipartFile对象,从而省略原生上传中分析请求体的步骤。

2.1 配置文件解析器

<!-- 文件解析器对象,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.2  创建JSP表单

upload2,.jsp

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

 其实这个JSP和上面那个没什么区别,只是响应处理的路径不同,为了避免重复开关tomcat,因为就多编写了一个表单。

2.3 控制器方法

// MultipartFile参数名必须和JSP文件空间的name属性一致
    @RequestMapping("/fileUpload2")
    public String upload2(MultipartFile file,HttpServletRequest request) throws Exception{
        // 创建文件夹,存放上传文件
        String realpath = request.getSession().getServletContext().getRealPath("/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";
    }

Ok,可以看到这个比上面那个简单许多,只需要参数名和表单的name属性一致便可以自动匹配。

2.4 测试结果

OK,访问路径:http://localhost:8080/upload2.jsp 

看到如下图,我们是成功上传了呢

三、上传多文件

SpringMVC支持一次性上传多个文件,写法如下:

3.1 JSP页面

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

3.2 控制器方法

// 处理多文件上传,参数类型为MultipartFile数组参数名和JSP文件控件的name属性一致
    @RequestMapping("/fileUpload3")
    public String upload3(MultipartFile files[],String username,HttpServletRequest request) throws Exception{
        System.out.println(username);
        // 1.设置上传文件保存的文件夹
        String realPath = request.getSession().getServletContext().getRealPath("/upload/files");
        File dir = new File(realPath);
        if(!dir.exists()){
            dir.mkdirs();
        }
        // 2.遍历数组,将上传文件保存到文件夹
        for(MultipartFile file:files){
            String filename = file.getOriginalFilename();
            filename = UUID.randomUUID()+"_" +filename;
            File newFile = new File(dir,filename);
            file.transferTo(newFile);
        }
        return "index";
    }

这里我们可以知道,方法参数名改一下类型即可, 并且表单的文件name必须要一致,上传后的文件放在upload文件夹子文件夹files里。

3.3 测试结果 

OK,如下图,我们是可以成功添加了files文件夹,并且里面也是有文件的

往期专栏&文章相关导读 

     大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。

1. Maven系列专栏文章

Maven系列专栏Maven工程开发
Maven聚合开发【实例详解---5555字】

2. Mybatis系列专栏文章

Mybatis系列专栏MyBatis入门配置
Mybatis入门案例【超详细】
MyBatis配置文件 —— 相关标签详解
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填
Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分)
Mybatis分页查询——四种传参方式
Mybatis一级缓存和二级缓存(带测试方法)
Mybatis分解式查询
Mybatis关联查询【附实战案例】
MyBatis注解开发---实现增删查改和动态SQL
MyBatis注解开发---实现自定义映射关系和关联查询

3. Spring系列专栏文章

Spring系列专栏Spring IOC 入门简介【自定义容器实例】
IOC使用Spring实现附实例详解
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式
Spring DI简介及依赖注入方式和依赖注入类型
Spring IOC相关注解运用——上篇
Spring IOC相关注解运用——下篇
Spring AOP简介及相关案例
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】
Spring事务简介及相关案例
Spring 事务管理方案和事务管理器及事务控制的API
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

4. Spring MVC系列专栏文章  

SpringMVC系列专栏Spring MVC简介附入门案例
Spring MVC各种参数获取及获取方式自定义类型转换器和编码过滤器
Spring MVC获取参数和自定义参数类型转换器及编码过滤器
Spring MVC处理响应附案例详解
Spring MVC相关注解运用 —— 上篇

Spring MVC相关注解运用 —— 中篇

Spring MVC相关注解运用 —— 下篇
Spring MVC多种情况下的文件上传
Spring MVC异步上传、跨服务器上传和文件下载
Spring MVC异常处理【单个控制异常处理器、全局异常处理器、自定义异常处理器】
Spring MVC拦截器和跨域请求
SSM整合案例【C站讲解最详细流程的案例】
  • 112
    点赞
  • 130
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 93
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 93
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会洗碗的CV工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值