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

news2024/9/21 22:46:03

一、原生方式上传

上传是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站讲解最详细流程的案例】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/736154.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SPSS数据排序

1.个案排序 &#xff08;1&#xff09;打开数据文件&#xff0c;选择“数据”——“个案排序”&#xff0c;弹出如下图所示的对话框&#xff0c;选中“树高”&#xff0c;再选择排序&#xff08;默认&#xff09; &#xff08;2&#xff09;选中“枝下高”&#xff0c;移到右边…

【IDEA】IDEA 版 Postman 新版发布,功能强大!

介绍 Restful Fast Request 是 IDEA 版 Postman&#xff0c;它是一个强大的 restful api 工具包插件&#xff0c;可以根据已有的方法帮助您快速生成 url 和 params。Restful Fast Request API 调试工具 API 管理工具 API 搜索工具。它有一个漂亮的界面来完成请求、检查服务…

智慧校园管理系统前台任意文件上传

如果沉醉满足于自己以往的历史就无异于生命大限的终临&#xff0c;人生旅程时刻处于“零公里”处。那么&#xff0c;要旨仍然应该是首先战胜自己&#xff0c;并将精神提升到不断发展着的生活所要求的那种高度&#xff0c;才有可能使自己重新走出洼地&#xff0c;亦步亦趋跟着生…

如何在Windows 11中轻松恢复意外删除的Chrome书签

当您意外删除了 Chrome 书签或书签文件夹时&#xff0c;您可以通过以下方法在 Windows 11 中恢复它们。Windows 11 中的 Chrome 浏览器提供了方便的恢复功能&#xff0c;让您可以轻松还原被删除的书签。 打开 Chrome 浏览器并导航到右上角的菜单按钮&#xff0c;点击打开菜单选…

ROS1到ROS2迁移教程(以rslidar_to_velodyne功能包为例)+ ROS2版本LIO-SAM试跑

一、引言 1、本博文主要目的是将rslidar_to_velodyne功能包的ros1版本转换为ros2版本 2、内容会包含ROS1到ROS2迁移技巧&#xff0c;是自己总结的一套简单的流程&#xff0c;可以保证ROS2下的代码试跑成功&#xff0c;如果需要将代码进一步转化为类的实现的方式&#xff0c;自…

开源教育对话大模型 EduChat

文章目录 一、&#x1f680; 前言二、&#x1f916; 本地部署三、&#x1f468;‍&#x1f4bb; 使用示例四、&#x1f50e; 总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、&#x1f680; 前言 教育是一项对人类身心发展产生影响的社会实践…

Elasticsearch 8.X 聚合查询下的精度问题及其解决方案

1、线上环境问题 咕泡同学提问&#xff1a;我在看runtime文档的时候做个测试&#xff0c; agg求avg的时候不管是double还是long&#xff0c;数据都不准确&#xff0c;这种在生产环境中如何解决啊&#xff1f; 2、问题归类及出现场景 上述问题可以归类为&#xff1a;Elasticsear…

【计算机组成与体系结构Ⅰ】实验3 微程序控制器实验

一、实验目的 了解微程序控制器的组成原理 二、实验设备 TEC-4实验系统、万用表 三、实验内容 1&#xff1a;阅读微指令格式和微程序控制器的组成&#xff0c;微指令由操作控制和顺序控制两部分组成&#xff0c;1条微指令的字长35位&#xff08;一个存储单元35位&#xff0c;采…

xml建模----详细完整,易懂结合代码分析

目录 一.XML建模是什么 二.XML建模有什么作用&#xff1f;&#xff1f;&#xff1f; 三.XML建模的案例 以config.xml为例 一.XML建模是什么 将XML配置文件中的元素、属性、文本信息转换成对象的过程叫做XML建模 二.XML建模有什么作用&#xff1f;&#xff1f;&#xff1f; …

Git命令操作【全系列】

Git常用命令操作 1 基础命令 ①git config --global user.name [‘你的用户名’]&#xff1a;查看/设置 git config --global user.name ziyi&#xff1a;设置用户名为ziyi git config --global user.name&#xff1a;查看用户名 ②git config --global user.email [‘你的邮…

React 在Dva项目中修改路由配置,并创建一个自己的路由

之后的话 我们还是来看一下Dva路由的配置 首先 我们在项目刚创建完 他就给了我们一个路径 叫routes 然后 IndexPage.js 是最初的一个组件 之前我们也用过了 然后 我们看到 src目录下的 index.js 这里 就有一个路由的匹配 他加载的就是 同目录下 一个 router的文件 我们点开…

外币兑换----贪心1 (爱思创)

源代码 #include <bits/stdc.h> using namespace std; int main() {double money,maxn-1,r;cin>>money;for(int i1;i<12;i){cin>>r;maxnmax(maxn,money*r);}printf("%0.2f",maxn);return 0; }

阿里云通义万相官网申请地址

通义万相刻削生千变&#xff0c;丹青图“万相”。我是通义万相&#xff0c;一个不断进化的AI绘画创作模型https://wanxiang.aliyun.com/现在申请的人少 应该好通过吧

软考高级之系统架构师系列之系统配置与性能评价、信息化基础

系统配置与性能评价 性能 计算机系统的性能一般包括两个大的方面&#xff1a; 可用性&#xff0c;也就是计算机系统能正常工作的时间&#xff0c;其指标可以是能够持续工作的时间长度&#xff0c;也可以是在一段时间内&#xff0c;能正常工作的时间所占的百分比处理能力&…

MySQL练习题(3)

创建数据库插入数据 CREATE TABLE emp ( empno int(4) NOT NULL, ename varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, job varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, mgr int(4) NULL DEFAULT N…

ndoe中express框架的基本使用,接收get、post请求,以及处理回调地狱的优雅解决方法

一、express框架的基本使用 Express框架是Node.js中最受欢迎的web开发框架&#xff0c;它的设计简洁而且功能强大&#xff0c;有着大量的插件和社区支持。 基于Express使用Node.js创建web应用的基本步骤如下&#xff1a; 首先你需要安装Node.js和npm&#xff08;Node包管理器…

拥抱简洁:探索Stylus的简洁语法与CSS预处理器之美

文章目录 1. 简洁的语法2. 强大的功能3. 嵌套规则4. 变量支持5. Mixin 混合6. 扩展支持7. 条件语句8. 内置函数9. 可扩展性10. 轻量高效附录&#xff1a;前后端实战项目&#xff08;简历必备&#xff09; 推荐&#xff1a;★★★★★ Stylus 是一种 CSS 预处理器&#xff0c;具…

OpenCV 入门教程:Laplacian算子和Canny边缘检测

OpenCV 入门教程&#xff1a; Laplacian 算子和 Canny 边缘检测 导语一、Laplacian 算子二、Canny 边缘检测三、示例应用3.1 图像边缘检测3.2 边缘增强 总结 导语 边缘检测在图像处理和计算机视觉领域中起着重要的作用。 Laplacian 算子和 Canny 边缘检测是两种常用的边缘检测…

pytorch-Tensor

神经网络的数据存储中都使用张量&#xff08;Tensor&#xff09;&#xff0c;那张量又是什么呢&#xff1f; py 张量这一概念的核心在于&#xff0c;它是一个数据容器。它包含的数据几乎总是数值数据&#xff0c;因此它是数字的容器。你可能对矩阵很熟悉&#xff0c;它是二…

商城小程序页面展示

——首页登录&#xff08;wx.login()&#xff0c;getPhoneNumber&#xff09; 进入首页时&#xff0c;加载商品列表数据展示在页面。从缓存中获取token信息&#xff0c;判断用户登录状态&#xff0c;如果用户没有登录&#xff0c;调用微信小程序的login方法&#xff0c;进行登…