ssm/springboot框架实现多文件上传–MultipartFile类+multiple属性+Ajax
首先搭建一个 SSM 或者 Spring Boot 项目,这里简单起见,项目就自行搭建了,直接用现成的一个 Spring Boot 项目来做这个功能实现。(代码可以直接用在两种项目上
)
接下来开始功能实现:
1.首先新建一个 upload.ftl 文件,如果用的是JSP就新建 upload.jsp,其他模板如thymeleaf、Freemarker、Velocity,就建相应的
,这里我这个项目已经配置了用freemarker,所以就直接新建 ftl 文件了。
增加一个 form 表单,form 表单里面添加两个控件,一个用来选择要上传的文件,一个是用来提交表单的按钮。
接下来,利用 ajax 来控制实现表单提交,这里在<head>
中引入 jQuery,方便开发
<script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
新建<Script>
标签编写JavaScript ,为上面的按钮绑定一个点击事件
写到这里,前端页面就算写好了,接下来写后端代码。新建一个 / 利用现有的 XxxxController.java 中创建两个方法,一个跳转到上传页面,一个实现上传功能。如下:
跳转页面方法:
实现上传功能方法:
到这里,SSM / Spring Boot 框架的多文件上传功能就已经实现了。下面开始测试。启动项目
浏览器输入:http://localhost:8081/cjcc,这里的 /cjcc 就是上面 controller 方法的 @GetMapping("/cjcc")
,并按 F12 打开开发人员工具–> newwork,方便测试。
点击选择文件按钮,选择需要上传的文件
上传成功之后,查看 Java 的控制台,看看设置输出的内容
至此,多文件已经成功上传。
本次写的多文件上传主要用到了:
1.MultipartFile 类
import org.springframework.web.multipart.MultipartFile;
MultipartFile 类是用来接收前台传过来的文件,常用的方法如下:
String getContentType() //获取文件MIME类型
InputStream getInputStream() //获取文件流
String getName() //获取表单中文件组件的名字
String getOriginalFilename() //获取上传文件的原名
long getSize() //获取文件的字节大小,单位byte,除以1024就是kb
boolean isEmpty() //是否为空
void transferTo(File dest) //保存到一个目标文件中。
2.multiple属性(HTML5 新属性
)
multiple 属性是一个布尔属性。
multiple 属性规定允许用户输入到 <input> 元素的多个参数值。
注意:multiple 属性适用于以下 input 类型:email 和 file。
例如:
<!--上传表单-start-->
<form enctype="multipart/form-data" id="form" method="post">
<!--构造一个input控件,类型为 file, HTML5中 multiple 属性规定输入字段可选择多个值 -->
<input name="file" type="file" multiple>
<!--构造一个input控件,为控件绑定一个id=upload,类型为 button,名称为:上传-->
<input id="upload" type="button" value="上传">
</form>
<!--上传表单-end-->
3.jQuery的Ajax
AJAX = 异步 JavaScript 和 XML(Asynchronous JavaScript and XML)。
简短地说,在不重载整个网页的情况下,AJAX 通过后台加载数据,并在网页上进行显示。
GET 基本上用于从服务器获得(取回)数据。注释:GET 方法可能返回缓存数据。
POST 也可用于从服务器获取数据。不过,POST 方法不会缓存数据(请求头中的Cache-Control: no-cache),并且常用于连同请求一起发送数据。
功能完整代码:
HTML:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>ssm/springboot框架实现多文件上传</title>
<!--引入jQuery-->
<script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<h2>多文件上传</h2>
<!--上传表单-start-->
<form enctype="multipart/form-data" id="form" method="post">
<!--构造一个input控件,类型为 file, HTML5中 multiple 属性规定输入字段可选择多个值 -->
<input name="file" type="file" multiple>
<!--构造一个input控件,为控件绑定一个id=upload,类型为 button,名称为:上传-->
<input id="upload" type="button" value="上传">
</form>
<!--上传表单-end-->
</body>
<script>
/**
* 上传按钮的点击事件
*/
$("#upload").click(function () {
//因为new FormData(HtmlElement),需要的是HtmlElement类型,如果利用jQuery获取,得到的是一个HtmlElement的集合,所以我们要取第一个值需要加下标$("#form")[0]
//JQuery 写法 $("#form")[0] 等价于原生JavaScript的 document.getElementById("form");
//既然这里已经导入了jQuery,那就用jQuery版本的写法
var formData = new FormData($("#form")[0]);
//发送 ajax 请求
$.ajax("/uploadVideo2", {
method: "POST", //请求类型
data: formData, //请求数据
async: false, //不开启异步,异步就是在执行到$.ajax({})的时候新开一个线程执行请求,主线程继续往$.ajax({})函数下面执行,等到后端返回请求结果之后再触发success或者error函数
cache: false, //不使用缓存,GET请求需要可以加,这里的POST请求本身就不会被缓存
contentType: false, //避免jQuery影响上面form表单设置的 enctype="multipart/form-data"类型,在F12中可以看到Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryW44OhJyyAytghmVT,"multipart/form-data"类型包含了boundary分界线作为多文件之间区分的边界
processData: false, //避免data数据转化为字符串,在application/x-www-form-urlencoded”
success: function (data) { //操作成功
alert(data);
},
error: function (result) {//操作失败
alert("添加失败");
}
});
return false;
})
</script>
</html>
Java-Controller代码:
package com.hh.onlinelearning.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
/**
* @author CJCC
*/
@Controller
public class IndexController {
/**
* 跳转到上传页面
* @return
*/
@GetMapping("/cjcc") // 浏览器地址栏输入的路径
public String index2() {
// 项目文件夹 resource/templates/自定义文件夹/upload.ftl的路径
// ftl是freemarker模板引擎文件后缀,用其他引擎的如JSP也是一样的,在配置文件里改响应的后缀就好了。
return "management/upload";
}
/**
* 上传
* @param files
* @return
*/
@PostMapping("/uploadVideo2")// 浏览器地址栏输入的路径
@ResponseBody
public String uploadVideo2(@RequestParam("file")MultipartFile[] files) throws IOException {
/**
* MultipartFile类是用来接收前台传过来的文件,常用的方法如下:
* String getContentType() //获取文件MIME类型
* InputStream getInputStream() //获取文件流
* String getName() //获取表单中文件组件的名字
* String getOriginalFilename() //获取上传文件的原名
* long getSize() //获取文件的字节大小,单位byte,除以1024就是kb
* boolean isEmpty() //是否为空
* void transferTo(File dest) //保存到一个目标文件中。
*/
for (MultipartFile file : files) { //因为有上传多个文件,所以用的是MultipartFile[]数组,所以要遍历数组保存里面的每一个文件
String filePath = "D:/files/"; // 暂时设置保存在D盘的files目录下
System.out.println(" 文件名称: " + file.getOriginalFilename());
System.out.println(" 文件大小: " + file.getSize() / 1024D + "Kb");
System.out.println(" 文件类型: " + file.getContentType());
System.out.println();
//在这里执行调用文件保存的方法....
filePath = filePath + file.getOriginalFilename();
file.transferTo(new File(filePath));
filePath = "";
//其他业务代码如插入数据库代码省略.........
}
return "添加成功";
}
}