目录
1.准备工作
1.创建Springboot项目添加web依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.创建upload.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>上传单个文件到服务器路径下</h2>
<form action="/uploadServerFile" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" value="请选择文件">
<input type="submit" value="上传">
</form>
<h2>上传单个文件</h2>
<form action="/uploadPahtFile" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" value="请选择文件">
<input type="submit" value="上传">
</form>
<h2>上传多个文件</h2>
<form action="/uploadPahtFiles" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFiles" value="请选择文件" multiple="multiple">
<input type="submit" value="上传">
</form>
</body>
</html>
enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。
默认地,表单数据会编码为 “application/x-www-form-urlencoded”。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值)
值描述application/x-www-form-urlencoded在发送前编码所有字符(默认)multipart/form-data不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。text/plain空格转换为 “+” 加号,但不对特殊字符编码。
2.单文件上传
创建文件上传接口
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FileUploadController {
//以时间作为文件夹
static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
@PostMapping("/uploadServerFile")
public String uploadServerFile(MultipartFile uploadFile, HttpServletRequest req) {
if ("".equals(uploadFile.getOriginalFilename())){
return "";
}
//文件存在的物理路径,但会随着项目的重新启动而改变
String realPath =
req.getSession().getServletContext().getRealPath("/uploadFile/");
System.out.println(realPath);
String format = sdf.format(new Date());
File folder = new File(realPath + format);
String filePath="";
if (!folder.isDirectory()) {
folder.mkdirs();
}
//当前文件名
String oldName = uploadFile.getOriginalFilename();
//新文件名
String newName = UUID.randomUUID().toString() +
oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
//将接收到的文件传输到给定的目标文件。
uploadFile.transferTo(new File(folder, newName));
//项目访问文件的路径
filePath = req.getScheme() + "://" + req.getServerName() + ":" +
req.getServerPort() + "/uploadFile/" + format + newName;
} catch (IOException e) {
e.printStackTrace();
return "上传失败! ";
}
return filePath;
}
}
其对应html的第一个表单,然后上传文件测试。
选择文件后点击上传按钮,显示如下,返回的路径可以通过通过浏览器访问。
单文件上传优化
但是这样做是有问题,上传图片到服务器根路径下的文件夹里,若重启服务器,图片则无法访问,这是因为每次重启服务器之后,都会在系统临时文件夹内,创建一个新的服务器,图片就保存在这里,若重启,又会产生一个新的服务器,此时访问的就是新服务器的图片资源,而图片根本就不在新服务器内。
- windows的临时文件夹位置:
C:\Users\User\AppData\Local\Temp
开始修改
设置的图片保存路径的末尾必须有
/
,代码中默认保存路径最后已经带有
/
了
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FileUploadController {
//以时间作为文件夹
static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
//文件存放的路径
public static String fileSavePath="E:/uploadFile/";
@PostMapping("/uploadPahtFile")
public String uploadPahtFile(MultipartFile uploadFile, HttpServletRequest req) {
if ("".equals(uploadFile.getOriginalFilename())){
return "";
}
String filePath = "";
String format = sdf.format(new Date());
//固定物理路径
File folder = new File(fileSavePath + format);
//如果文件夹不存在则创建
if (!folder.isDirectory()) {
folder.mkdirs();//创建文件夹
}
//上传的文件名
String oldName = uploadFile.getOriginalFilename();
//新的文件名
String newName = UUID.randomUUID().toString() +
oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
//将uploadFile存到一个路径为:folder,名字为:newName的文件,
uploadFile.transferTo(new File(folder, newName));
//获取项目访问的路径
filePath = req.getScheme() + "://" + req.getServerName() + ":" +
req.getServerPort() + "/uploadFile/" + format + newName;
} catch (IOException e) {
e.printStackTrace();
return "上传失败! ";
}
return filePath;
}
}
其对应html的第二个form,选择这种方式时需要对静态资源进行映射
** 添加配置类,配置资源映射**
import com.li.utils.FileUploadUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 图片保存路径,自动从yml文件中获取数据
* 示例: E:/uploadFile/
*/
private String fileSavePath= "E:/uploadFile/";
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 配置资源映射
* 意思是:如果访问的资源路径是以“/uploadFile/”开头的,
* 就给我映射到本机的“E:/uploadFile/”这个文件夹内,去找你要的资源
* 注意:E:/uploadFile/ 后面的 “/”一定要带上
*/
registry.addResourceHandler("/uploadFile/**")
.addResourceLocations("file:"+fileSavePath);
}
}
之后同上进行测试。
这时上传后再重启项目,依然可以访问之前上传的文件。
静态资源位置除了classpath下面的4个路径之外,还有一个"/",因此这里的图片虽然是静态资源却可以直接访问到。
一文件上传的配置参数:
#是否开启文件上传支持,默认为true。
spring. servlet.multipart.enabled=true
#文件写入磁盘的阈值,默认为0。
spring.servlet.multipart.file-size-threshold=0
#上传文件的临时保存位置。
spring.servlet.multipart.location=E:ltemp
#上传的单个文件的最大大小,默认为1MB。
spring.servlet.multipart.max-file-size=1MB
#多文件上传时文件的总大小,默认为10MB。
spring.servlet.multipart.max-request-size=10MB
#文件是否延迟解析,默认为false。
spring.servlet.multipart.resolve-lazily=false
3.多文件上传
再上一个为基础进行修改,将原本接收的的MultipartFile对象变成数组
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FileUploadController {
//以时间作为文件夹
static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
//文件存放的路径
public static String fileSavePath="E:/uploadFile/";
@PostMapping("/uploadPahtFiles")
public static List<String> uploadPahtFiles(MultipartFile[] uploadFiles, HttpServletRequest req) {
//所传入文件项目访问路径的集合
ArrayList<String> filePathlist=new ArrayList();
String filePath = "";
for(MultipartFile uploadFile:uploadFiles){
//如果文件名位空,则不保存
if ("".equals(uploadFile.getOriginalFilename())){
continue;
}
String format = sdf.format(new Date());
File folder = new File(fileSavePath + format);
if (!folder.isDirectory()) {
folder.mkdirs();
}
String oldName = uploadFile.getOriginalFilename();
String newName = UUID.randomUUID().toString() +
oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
uploadFile.transferTo(new File(folder, newName));
filePath = req.getScheme() + "://" + req.getServerName() + ":" +
req.getServerPort() + "/uploadFile/" + format + newName;
} catch (IOException e) {
e.printStackTrace();
}
//将访问路径放入集合中
filePathlist.add(filePath);
}
return filePathlist;
}
}
注:multiple="multiple" 是倍数(多选)的意思,再input标签中加上他就可以按Ctrl进行多选了。
<input type="file" name="file" multiple="multiple"/>
4.整合为工具类
对其整合成工具类以便使用
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* 文件上传工具类
*/
public class FileUploadUtil {
//以时间作为文件夹
static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
//文件存放的路径
public static String fileSavePath="E:/uploadFile/";
/**
* 上传文件到指定路径中,
* 例如 fileSavePath=E:/uploadFile/"
* @param uploadFile uploadPahtFile
* @param req request
* @return 返回通过项目访问文件的路径(需要配置资源映射)
*/
public static String uploadPahtFile(MultipartFile uploadFile, HttpServletRequest req) {
if ("".equals(uploadFile.getOriginalFilename())){
return "";
}
String filePath = "";
String format = sdf.format(new Date());
//固定物理路径
File folder = new File(fileSavePath + format);
//如果文件夹不存在则创建
if (!folder.isDirectory()) {
folder.mkdirs();//创建文件夹
}
//上传的文件名
String oldName = uploadFile.getOriginalFilename();
//新的文件名
String newName = UUID.randomUUID().toString() +
oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
//将uploadFile存到一个路径为:folder,名字为:newName的文件,
uploadFile.transferTo(new File(folder, newName));
//获取项目访问的路径
filePath = req.getScheme() + "://" + req.getServerName() + ":" +
req.getServerPort() + "/uploadFile/" + format + newName;
} catch (IOException e) {
e.printStackTrace();
return "上传失败! ";
}
return filePath;
}
/**
* 上传文件到服务器路径,
* 当上传过后项目再一次启动则会改变之前的路径,
* 之前的文件也无法访问到了,但是还存在再电脑的临时文件夹 Temp 中
* @param uploadFile 上传的文件
* @param req request
* @return 返回通过项目访问文件的路径(不需要配置资源映射)
*/
public static String uploadServerFile(MultipartFile uploadFile, HttpServletRequest req) {
if ("".equals(uploadFile.getOriginalFilename())){
return "";
}
//文件存在的物理路径,但会随着项目的重新启动而改变
String realPath =
req.getSession().getServletContext().getRealPath("/uploadFile/");
System.out.println(realPath);
String format = sdf.format(new Date());
File folder = new File(realPath + format);
String filePath="";
if (!folder.isDirectory()) {
folder.mkdirs();
}
//当前文件名
String oldName = uploadFile.getOriginalFilename();
//新文件名
String newName = UUID.randomUUID().toString() +
oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
//将接收到的文件传输到给定的目标文件。
uploadFile.transferTo(new File(folder, newName));
//项目访问文件的路径
filePath = req.getScheme() + "://" + req.getServerName() + ":" +
req.getServerPort() + "/uploadFile/" + format + newName;
} catch (IOException e) {
e.printStackTrace();
return "上传失败! ";
}
return filePath;
}
/**
* 上传多个文件到指定路径中
* @param uploadFiles uploadPahtFile
* @param req request
* @return 返回通过项目访问文件的路径的集合(需要配置资源映射)
*/
public static List<String> uploadPahtFiles(MultipartFile[] uploadFiles, HttpServletRequest req) {
//所传入文件项目访问路径的集合
ArrayList<String> filePathlist=new ArrayList();
String filePath = "";
for(MultipartFile uploadFile:uploadFiles){
//如果文件名位空,则不保存
if ("".equals(uploadFile.getOriginalFilename())){
continue;
}
String format = sdf.format(new Date());
File folder = new File(fileSavePath + format);
if (!folder.isDirectory()) {
folder.mkdirs();
}
String oldName = uploadFile.getOriginalFilename();
String newName = UUID.randomUUID().toString() +
oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
uploadFile.transferTo(new File(folder, newName));
filePath = req.getScheme() + "://" + req.getServerName() + ":" +
req.getServerPort() + "/uploadFile/" + format + newName;
} catch (IOException e) {
e.printStackTrace();
}
//将访问路径放入集合中
filePathlist.add(filePath);
}
return filePathlist;
}
}
//配置资源映射的配置类
//@Configuration
//public class WebConfig implements WebMvcConfigurer {
// /**
// * 图片保存路径,自动从yml文件中获取数据
// * 示例: E:/uploadFile/
// */
// private String fileSavePath= FileUploadUtil.fileSavePath;
//
// @Override
// public void addResourceHandlers(ResourceHandlerRegistry registry) {
// /**
// * 配置资源映射
// * 意思是:如果访问的资源路径是以“/uploadFile/”开头的,
// * 就给我映射到本机的“E:/uploadFile/”这个文件夹内,去找你要的资源
// * 注意:E:/uploadFile/ 后面的 “/”一定要带上
// */
// registry.addResourceHandler("/uploadFile/**")
// .addResourceLocations("file:"+fileSavePath);
// }
//}
//文件上传的配置参数
//#是否开启文件上传支持,默认为true。
//spring. servlet.multipart.enabled=true
//#文件写入磁盘的阈值,默认为0。
//spring.servlet.multipart.file-size-threshold=0
//#上传文件的临时保存位置。
//spring.servlet.multipart.location=E:ltemp
//#上传的单个文件的最大大小,默认为1MB。
//spring.servlet.multipart.max-file-size=1MB
//#多文件上传时文件的总大小,默认为10MB。
//spring.servlet.multipart.max-request-size=10MB
//#文件是否延迟解析,默认为false。
//spring.servlet.multipart.resolve-lazily=false
以上就是Spring boot对文件的上传了。
版权归原作者 五十六精研 所有, 如有侵权,请联系我们删除。