SpringMVC上传文件


前言

本文介绍前端HTML界面如何向后端发送文件的两种方式: form表单上传和Ajax上传两种方式,本文是基于Spring Boot项目的Web应用。之前在解决文件上传问题时走了不少弯路,在项目完成以后写下博客来记录自己的解决方法,以后再遇到类似的问题将不会再发生之前犯过的错误,如果内容有解释描述不妥之处,欢迎在评论区指出。

送给阅读本文读者的一段话:之前做项目时这些方法我也不会,在实现的过程中也是一直遇到各种各样的问题,我也查阅了网络上很多的博客和案例。但是我在点开博客时看到没有讲解只有代码时就立刻关闭,没有静下心来去好好的理解代码,可能有很多读者和我的心态是一样的,所以在这里想跟和我以前一样心态的读者说一句:亲爱的读者朋友,感谢你点开这篇文章,如果你和我一样有很焦急迫切的心态的话,希望此刻你能静下心来看一看我写的内容,我相信咱们遇到的问题是相似的,有了之前自己希望博文中能够出现的内容,所以我会在博文中加入相应的内容。再次感谢你能看到这里,我也自信我的这篇博文能够帮助到你。


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

本文案例基于SpringBoot实现,以上传Excel文件为例,因为这里只涉及到了Controller层,pom.xml文件中的依赖以及其余层的内容在此不多做赘述

一、form表单上传

1、样例代码:

HTML代码

<!DOCTYPE html>
<html>
<head>
    <title>上传文件</title>
    <meta content="text/html" charset="UTF-8">
</head>
<body>
<h1>上传文件</h1>
<form action="/upload" enctype="multipart/form-data" method="post">
    <table>
        <tr>
            <td>文件描述:</td>
            <td><input type="text" name="mess"></td>
        </tr>
        <tr>
            <td>选择文件:</td>
            <td><input type="file" id="file" name="file"></td>
        </tr>
        <tr>
            <td><input type="submit" value="上传" name="btn" id="btn"></td>
        </tr>
    </table>
</form>
</body>
</html>

Controller层代码

package com.example.demo.controller;

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;

/**
 * @author Dream_飞翔
 * @email 1072876976@qq.com
 */
@Controller
public class MessController {
    @RequestMapping("upload")
    @ResponseBody
    public String upLoad(String mess, MultipartFile file){
        System.out.println(mess);
        System.out.println(file.getOriginalFilename());
        return "success";
    }
}

2、运行结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、代码解析:

HTML代码

<form action="/upload" enctype="multipart/form-data" method="post">
...
</form>

利用form表单上传文件时要将enctype属性的属性值设置为multipart/form-data,其次要将method的属性值设置为postaction属性的值为请求的路径(与Controller层中的@requestMapping注解中的值对应,注意要加" / "

原因:

  1. enctype属性的属性值设置为multipart/form-data
    enctype="multipart/form-data"的意思其实就是设置表单的MIME编码。默认情况的编码格式是application/x-www-form-urlencoded,将表单中的数据变为键值对的形式,不能用于文件的上传。而enctype="multipart/form-data"是将表单中的数据变成二进制数据进行上传(也就是说将文件转换成二进制数据进行上传)。
  2. method的属性值设置为post
    method的属性值设置为post有多种原因,其中最主要的原因就是:Get方式是用来从服务器上获得数据,而 Post方式是用来向服务器上传递数据 ,其次就是Get 是不安全的,因为在传输过程,数据被放在请求的URL中,除了可能会有一些隐私的信息被第三方看到外,用户也可以在浏览器上直接看到提交的数据,一些系统内部消息将会一同显示在用户面前。而Post 的所有操作对用户来说都是不可见的

Controller层代码

 @RequestMapping("upload")
 @ResponseBody
 public String upLoad(String mess, MultipartFile file){
 ...
	 return "success";
 }

注解解析:
第一行注解的意思为截取到请求名称为upload的动作这里的值与HTML页面中form表单中的action的属性值一致.,本质上就是将action的动作截取到,执行注解对应方法中的方法体内容 (在SpringMVC的源码中处理页面请求时用到的底层技术还是Servlet)
第二行注解的意思,在解释第二行代码的意思前先看方法头的返回值为String类型,在Controller层中当方法的返回值为String类型时有两种情况,当方法头前加有@ResponseBody注解时,return的内容将会展示在前端页面上。注意:此时返回前端的是Json对象而不是Json串当方法头前不加@responseBody注解时将会跳转到对应名称的HTML界面,所以此时当文件上传成功后就将"success"打印到前端界面上

方法解析:
返回值类型为String类型,因为在方法头前加有@ResponseBody注解,因此当文件上传成功后会将return的内容打印到前端显示。第一个参数是获取到前端form表单中的输入的文字信息,对应前端如下语句:

<td>文件描述:</td>
<td><input type="text" name="mess"></td>

第二个参数是MultipartFile本质上是SpringMVC框架为我们提供简化上传操作的工具类,在前端HTML页面上传文件时是将文件转换成二进制字节流来传到后端,如果不使用MultipartFile工具类的话我们只能用HttpServletRequest来接收上传的数据,再手动将二进制流转化为File文件。MultipartFile的出现简化了我们的操作,此时file就是我们传到后端的文件

file.getOriginalFilename()

getOriginalFilename()为获取到文件的名称

二、Ajax上传

1、样例代码:

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ajax上传文件</title>
    <script type="text/javascript" src="/js/jquery-3.5.1.min.js"></script>
</head>
<body>
<h1>Ajax上传文件</h1>
<table>
    <tr>
        <td>文件上传</td>
    </tr>
    <tr>
        <td>文件描述:</td>
        <td><input type="text" name="mess" id="mess"></td>
    </tr>
    <tr>
        <td>上传文件</td>
        <td><input type="file" name="file" id="upfile"></td>
    </tr>
    <tr>
        <td><input type="submit" onclick="checkFile()" value="上传"/></td>
    </tr>
</table>
</body>
<script>
	// 在使用Ajax上传文件之前要先导入jQuery
    function checkFile() {
        var formData = new FormData();
        formData.append('file', $('#upfile')[0].files[0]);
        $.ajax({
            url:"/uploadSecond",
            type:"POST",
            data:formData,
            cache:false,
            processData:false,
            contentType:false,
            dataType: 'json',
            success:function (data) {
                // console.log(data);
                if (data == "1")
                    alert("上传成功");

            },
            error:function (data) {
                if (data == "0")
                    alert("上传失败");
            }
        });
    }
</script>
</html>

Controller层代码

package com.example.demo.controller;

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;

/**
 * @author Dream_飞翔
 * @email 1072876976@qq.com
 */
@Controller
public class MessController {
    @RequestMapping("uploadSecond")
	@ResponseBody
	public String upLoadSecond(MultipartFile file){
		System.out.println(file.getOriginalFilename());
		return "1";
    }
}

2、运行结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、代码解析:

HTML代码

<table>
    <tr>
        <td>文件上传</td>
    </tr>
    <tr>
        <td>文件描述:</td>
        <td><input type="text" name="mess" id="mess"></td>
    </tr>
    <tr>
        <td>上传文件</td>
        <td><input type="file" name="file" id="upfile"></td>
    </tr>
    <tr>
        <td><input type="submit" onclick="checkFile()" value="上传"/></td>
    </tr>
</table>

与之前form表单上传文件的方式大致相同,不同点在于利用Ajax上传文件不需要使用form表单,但是在type类型为submit的<input>标签中需要添加一个单击事件,这个单击事件用于将用于处理要上传的文件

JavaScript代码

<script>
	// 在使用Ajax上传文件之前要先导入jQuery
    function checkFile() {
        var formData = new FormData();
        formData.append('file', $('#upfile')[0].files[0]);
        $.ajax({
            url:"/uploadSecond",
            type:"POST",
            data:formData,
            cache:false,
            processData:false,
            contentType:false,
            dataType: 'json',
            success:function (data) {
                if (data == "1")
                    alert("上传成功");

            },
            error:function (data) {
                if (data == "0")
                    alert("上传失败");
            }
        });
    }
</script>

需要注意的是在使用Ajax上传文件之前要先导入jQuery

function checkFile() {
...
}

因为之前在<input>标签中添加了单击事件,添加的单击事件在这里进行定义做出怎样的处理

var formData = new FormData();

Ajax上传文件时传到后端的对象就是formData,也就是说我们是将这个formData对象传到了后端,所以在Ajax正式上传文件之前先声明formData对象

formData.append('file', $('#upfile')[0].files[0]);

在声明了一个formData对象以后,此时对象当中什么都没有,所以这个时候就要将想要上传的文件添加到formData对象中,append()方法中的第一个参数的意思为要添加到formData对象中的数据的类型为文件类型,第二个参数为文件对象,即$(’#file’)[0].files[0]就是我们要上传的文件

$.ajax({
            url:"/uploadSecond",
            type:"POST",
            data:formData,
            cache:false,
            processData:false,
            contentType:false,
            dataType: 'json',
            success:function (data) {
                if (data == "1")
                    alert("上传成功");

            },
            error:function (data) {
                if (data == "0")
                    alert("上传失败");
            }
        });
    }
  1. $.ajax({…});为Ajax上传文件的标准形式,url对应的值为数据接口(就是后面要被Controller层中拦截的值
  2. type提交方式为post,原因与form表单提交方式一致,在此不多做赘述
  3. data为提交的数据,此时我们将formData对象整体进行上传
  4. cache的值设置为false是因为上传文件不需要缓存
  5. processData的值设置为false是因为data值也就是我们要上传的数据是FormData对象,不需要对数据做出处理
  6. dataType的意思为返回值为json格式的数据
  7. success:如果上传成功就执行这个function,这个方法中的参数data就是Controller层中返回的json对象,如果返回的json对象的值为1就在页面弹出提示框显示上传成功
  8. error:与success的思路一致,如果上传失败就执行error后面的function,如果返回的json对象的值为0则弹出上传失败的提示框

Controller层代码

@RequestMapping("uploadSecond")
@ResponseBody
public String upLoadSecond(MultipartFile file){
	System.out.println(file.getOriginalFilename());
	return "1";
}

与form表单上传文件的代码思路一致,不同点在于返回前端的json对象的内容


总结

以上便是HTML界面如何上传文件的两种方式,本文用了一个简单的案例来讲述两种上传文件方法的原理,在理解了以后再回首看这些操作其实并没有那么复杂,但是在一开始没有静下心来认真的去理解一,所以才耗费了更多的时间。在此做一个记录,以后不允许自己再犯类似的错误,遇到问题时哪怕时间再紧张也要稳下来。再次感谢读者朋友能够看到这里,如果文章中有讲解不妥的地方欢迎在评论区指出,很高兴能够一起进步!

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Dream_飞翔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值