写个基本的前端form表单页面,用于选择文件上传。由于是上传文件,请求的差异就体现出来了。**上传文件只能使用post请求,并且需要设置enctype=“multipart/form-data”**表示这是一个包含文件的表单。
注意事项:文件上传表单采用编码方式multipart/form-data 与 正常url编码不同,getParameter方法不能使用 setCharacterEncoding 无法解决输入项乱码问题
<div>
<form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/upload.do">
<p>用户: <input type="text" name="user"></p>
<p>文件1: <input type="file" name="file1"></p>
<p>文件2: <input type="file" name="file2"></p>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</div>
文件上传所需的核心API的Maven依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
完成文件上传需要三个API核心接口:
-
DiskFileItemFactory磁盘文件工厂类:设置缓存大小以及临时文件保存位置。
setDefaultCharset("utf-8") 设置编码格式 setSizeThreshold(1024*1024) 设置内存缓冲大小为1mb setRepository(String path) 当文件大小超过内存缓冲区大小时存放的路径
内存缓冲区:上传文件的内容优先保存在内存缓冲区中,当上传文件大小超过缓冲区大小,就会产生一个临时文件tmp类型文件(俗称垃圾文件)
临时文件存放位置: 保存超过了内存缓冲区大小上传文件而产生临时文件
-
ServletFileUpload文件上传核心类:该类通过磁盘文件工厂获取到上传文件的缓冲区、临时文件地址。
setHeaderEncoding("utf-8"); 设置编码 setSizeMax(1024*1024*100); 限制单次请求能够上传的文件大小(单位字节) 100mb setFileSizeMax(20*1024*1024); 限制单个文件大小 20mb isMultipartContent(request) 判断request请求中是否是enctype="multipart/form-data"类型 parseRequest(request) 解析request请求中携带的数据(包括文件)
-
FileItem文件项目类:parseRequest(request)解析后得到的是List< FileItem >线性表,request对象中所有的数据:输入的数据、上传文件… 都是一个个的FileItem
isFormField(); 表单的一个普通字段返回true, 文件返回false getFieldName(); 获得当前字段的名字 即前端input中的 name 参数 getString("utf-8") 以utf-8编码形式加载name 参数的 数据 getName(); 获得上传文件名 getInputStream() 获得上传文件内容输入流,这个流可能是临时文件也可能是缓冲区中的文件数据 delete() 用于删除产生的临时文件
-
getName()方法是比较特殊的,对于不同的浏览器上传的文件路径是不同的,使用的谷歌浏览器上传时只由文件名 + 类型。其他的浏览器可能囊括文件的全路径。
-
用户上传的文件也是五花八门的,可以限制用户上传文本的类型…
-
用户上传的文件必须进行唯一命名,解决方法:时间戳、MD5、UUID…
package com;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.UUID;
public class FileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 设置上传文件存放的路径
File dir = new File("D:\\file\\upload");
if(!dir.exists()){ //该路径不存在就建立一个
dir.mkdirs();
}
//2. 创建DiskFileItemFactory磁盘文件项工厂类,设置一些参数
DiskFileItemFactory dfif = new DiskFileItemFactory();
dfif.setDefaultCharset("utf-8"); //设置文件编码
dfif.setSizeThreshold(1024*1024); //设置内存临时缓冲区大小为1mb
dfif.setRepository(dir); //当上传的文件大于临时临时缓冲区时存放的位置
//临时文件目录 和 最终存放目录是同一个
//3. 获取ServletFileUpload文件上传对象
ServletFileUpload sf = new ServletFileUpload(dfif);
sf.setHeaderEncoding("utf-8");
//1k * 1024 * 100 = 100m 设置能够上传的文件总大小
sf.setSizeMax(1024*1024*100);
//设置单个文件大小 20mb
sf.setFileSizeMax(20*1024*1024);
//4. 对上传的数据进行解析
try {
List<FileItem> list = sf.parseRequest(req);
for (FileItem item : list) {
item.isFormField();
if(item.isFormField()){ //表单中的非文件数据
String name = item.getFieldName();
String value = item.getString("utf-8");
System.out.println(name + " : " + value);
}
else{
String name = item.getName();
System.out.println("上传的文件名: " + name);
if(name == null || name.equals("")){ //没有文件,跳掉
continue;
}
String FileType = name.substring(name.lastIndexOf(".") + 1); //.xxx类型
String FileName = name.substring(0,name.lastIndexOf(".")); //Filename.xxx文件名
System.out.println("文件名: " + FileName + ", 文件类型: " + FileType);
String uuid = UUID.randomUUID().toString(); //UUID获取一串随机数
String realpath = dir + "/" + uuid;
File file = new File(realpath);
file.mkdir(); //为这个文件建立一个文件夹
BufferedInputStream bis = new BufferedInputStream(item.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(realpath + "/" + name));
byte[] buf = new byte[1024*1024]; //1KB * 1024 = 1MB
int len = 0;
while((len = bis.read(buf)) != -1){
bos.write(buf,0,len);
bos.flush();
}
bos.close();
bis.close();
// item.delete(); //删除临时文件
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
}