文件上传
文件上传
1、准备工作
-
创建项目,用maven创建尽量不要手动导包,避免出现web.xml实例化错误。
-
导入common-io和common-fileupload包:
地址:https://mvnrepository.com/artifact/commons-io/commons-io/2.6
https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload/1.4
-
maven导包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
2、注意事项
-
为保证服务器安全,文件上传可存放在WEB-INF目录下
-
为防止文件覆盖,要使文件名不同,可用uuid
-
要限制文件大小
-
可以根据文件后缀限制文件格式
3、代码实现
-
判断前端请求的表单是否含有文件 enctype="multipart/form-data"
if (!ServletFileUpload.isMultipartContent(req)) {
return;
} -
因为get方法传的参数大小有限制,所以要用post方法 method="post"
<form action="${pageContext.request.contextPath}/f1" enctype="multipart/form-data" method="post">
<p><input type="text" name="name"><br>
<input type="file" name="file1"><br>
<input type="file" name="file2"><br>
<input type="submit"> | <input type="reset"></p>
</form> -
设置存放路径和临时存放路径
// 创建文件存放路径
String uploadPath = this.getServletContext().getRealPath("WEB-INF/uploadPath");
File uploadFile = new File(uploadPath);
if (!uploadFile.exists()) {
uploadFile.mkdir();
}
// 创建临时存放路径
String tmpPath = this.getServletContext().getRealPath("WEB-INF/tmpPath");
File file = new File(tmpPath);
if (!uploadFile.exists()) {
file.mkdir();
} -
创建 DiskFileItemFactory
public DiskFileItemFactory getDiskFileItemFactory(File file) {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(file); // 设置临时文件存放位置
factory.setSizeThreshold(1024 * 1024); /// 设置缓冲区大小
factory.setDefaultCharset("utf-8"); // 设置字符集
return factory;
} -
创建FileUpload
public FileUpload getFileUpload(DiskFileItemFactory factory) {
FileUpload upload = new FileUpload();
upload.setFileItemFactory(factory); // 也可以通过构造器传FileUpload upload = new FileUpload(factory);
upload.setFileSizeMax(1024 * 1024); // 设置文件最大为(单个文件最大) 1M
upload.setSizeMax(1024 * 1024 * 15); // 设置最大存放总量(所有文件加起来) 15m
upload.setHeaderEncoding("utf-8"); // 指定编码
upload.setProgressListener(new ProgressListener() { // 监听
-
封装文件对象,判断是否是文件,将文件转换为流, 拼接文件路径,写入服务器
public String msg(FileUpload upload, String uploadPath, HttpServletRequest req) {
List<FileItem> fileItems = null;
InputStream in = null;
FileOutputStream fos = null;
String msg = "文件上传失败";
try {
fileItems = upload.parseRequest(req);
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) { // 判断是否是文件, 不是则不用上传 true不是文件
String name = fileItem.getFieldName(); // 获取表单的name
String value = fileItem.getString("utf-8"); // 获取到输入的值
System.out.println(name + ":" + value);
} else {
String uploadFileName = fileItem.getName(); // 获取文件名路径
System.out.println("文件路径" + uploadFileName);
if (uploadFileName.trim().equals("") || uploadFileName == null) {
continue; // 如果文件名为空
}
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("\\") + 1); // 获取文件名
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); // 获取文佳格式
System.out.println("文件信息 [件名:" + fileName + "---文件类型" + fileExtName + "]");
// uuid创建文目录防止文件覆盖
String uuidPath = UUID.randomUUID().toString();
// 拼接文件存放路径
String realPath = uploadPath + "\\" + uuidPath;
File realPathFile = new File(realPath);
// 如果没有该目录创建目录
if (!realPathFile.exists()) {
realPathFile.mkdir();
}
// 将文件转变换为流
in = fileItem.getInputStream();
fos = new FileOutputStream(realPath + "\\" + fileName);
byte[] buffer = new byte[1024 * 1024];
int len = 0;
while ((len = in.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
msg =