目录
1.准备工作
1.创建Springboot项目添加web依赖
2.创建upload.html页面
2.单文件上传
创建文件上传接口
编辑 单文件上传优化
3.多文件上传
4.整合为工具类
org.springframework.boot
spring-boot-starter-web
Title
上传单个文件到服务器路径下
上传单个文件
上传多个文件
enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。
默认地,表单数据会编码为 “application/x-www-form-urlencoded”。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值)
值 | 描述 |
---|---|
application/x-www-form-urlencoded | 在发送前编码所有字符(默认) |
multipart/form-data | 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。 |
text/plain | 空格转换为 “+” 加号,但不对特殊字符编码。 |
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
再上一个为基础进行修改,将原本接收的的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 uploadPahtFiles(MultipartFile[] uploadFiles, HttpServletRequest req) {
//所传入文件项目访问路径的集合
ArrayList 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进行多选了。
对其整合成工具类以便使用
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 uploadPahtFiles(MultipartFile[] uploadFiles, HttpServletRequest req) {
//所传入文件项目访问路径的集合
ArrayList 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对文件的上传了。