项目结构及pom.xml
pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
创建文件表单页面
文件表单要求其 form标签中method="post" enctype="multipart/form-data"
,然后多文件表单的话,可以通过<input type="file" multiple>
multiple属性来声明这是一个多文件控件。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件表单上传</title>
</head>
<body>
<form th:action="@{/upload}" method="post" enctype="multipart/form-data">
邮箱:<input type="text" name="email"><br>
账号:<input type="text" name="idCard"><br>
头像:<input type="file" name="head_portrait"><br>
其他文件上传<input type="file" multiple name="fileLists"><br>
<input type="submit" value="上传"><br>
</form>
</body>
</html>
编写javabean
package com.robin.boot.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.ArrayList;
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Data
public class MyFileUpLoad {
// 封装javabean,用于success.html页面遍历数据
private String email;
private String idCard;
private String headImg;
private String[] names;
}
编写controller映射
MultipartFile类
在Spring框架中提供了MultipartFile来处理文件上传的文件。MultipartFile类是org.springframework.web.multipart
包下面的一个类,MultipartFile主要是用表单的形式进行文件上传,在接收到文件时,可以获取文件的相关属性,比如文件名、文件大小、文件类型等等。
MultipartFile类,提供了很多方法供我们使用,如下图:
@RequestPart注解
@RequestPart主要用来处理content-type为 multipart/form-data 或 multipart/mixed stream 发起的请求,可以获取请求中的参数,包括普通文本、文件或复杂对象比如json、xml等,针对json等复杂对象,需要明确对应的content-type。
使用时在@RequestPart(“xxx”),通过file表单控件的name值,即可获取对应元素的内容。
controller代码
获取上传的表单文件和普通控件的值,并将其存放于当前项目的静态资源下的uploadCaches文件夹中,同时如果上传成功的话,将上传的数据封装到javabean中,然后使用model将其发送至请求域中。
tip:这里图片上传的时候,封装到javabean中的是它的上传文件名,所以待会儿遍历时,使用img标签就可以看到上传的图片了。
使用MultipartFile类中提供的transferTo()方法可以直接将上传的文件保存到指定的位置中,getOriginalFilename()方法用于获取上传文件的文件名称。
package com.robin.boot.controller;
import com.robin.boot.bean.MyFileUpLoad;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@Slf4j
@Controller
public class FormTestController {
// 获取文件上传表单
@RequestMapping("/upload")
public String upload(@RequestParam("email") String email,
@RequestParam("idCard") String idCard,
@RequestPart("head_portrait") MultipartFile head_portrait,
@RequestPart("fileLists") MultipartFile[] fileLists,
Model model) throws IOException {
// 输出日志信息
log.info("email{},idCard{},head_protrait_size{},fileLists_length{}",
email,idCard,head_portrait.getSize(),fileLists.length);
String headImg = "";
// 保存上传的文件到当前项目的 static 目录下
if(!head_portrait.isEmpty()){
// 获取上传的头像的名字
headImg = "uploadCaches\\"+head_portrait.getOriginalFilename();
// 保存到 static目录中的 uploadCaches目录下
head_portrait.transferTo(new File("D:\\IdeaProjects\\demoUpload\\src\\main\\resources\\static\\"+headImg));
}
// 多文件名数组
String[] names = new String[fileLists.length];
// 保存多文件。一边遍历一边保存
if (fileLists.length>0){
for (int i = 0; i < fileLists.length; i++) {
if(!fileLists[i].isEmpty()){
// 与上面单个文件保存的方法一样
String filename = "uploadCaches\\"+fileLists[i].getOriginalFilename();
names[i] = filename;
fileLists[i].transferTo(new File("D:\\IdeaProjects\\demoUpload\\src\\main\\resources\\static\\"+filename));
}
}
}
// 创建javabean对象
MyFileUpLoad myFileUpLoad = new MyFileUpLoad(email,idCard,headImg,names);
// 跳转视图,并且封装数据到Model中
model.addAttribute("msg","保存成功!");
model.addAttribute("myFileUpLoad",myFileUpLoad);
return "success";
}
}
application.properties中的文件上传配置
可以通过spring.servlet.multipart.max-file-size
和spring.servlet.multipart.max-request-size
来设定服务器接受的文件上传的最大值。
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=20MB
遍历数据显示页面
使用thymeleaf的 th:each
以及 th:text
和th:src
将请求域中的数据获取,并且渲染到页面中。需要注意的是,thymeleaf的for-each遍历item:${Lists}
其子项${item.xxx}...
,要求其中的item.xxx
,xxx必须是和javabean中的字段名对应,而不是和model发送请求时的字段名保持一致。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>success</title>
</head>
<body>
<h3 th:text="${msg}">title</h3>
<div th:each="item:${myFileUpLoad}">
邮箱:<span th:text="${item.email}">xxx</span><br>
账号:<span th:text="${item.idCard}">xxx</span><br>
头像:<img th:src="${item.headImg}"></img><br>
其他文件:
<p th:each="nameItem:${item.names}">
<img th:src="${nameItem}" style="width: 240px;height: 240px"></img><br>
</p>
</div>
</body>
</html>