上传文件
文件上传过程
![](https://img2020.cnblogs.com/blog/1619135/202008/1619135-20200829191243070-801329897.png)
文件上传注意事项
- 1.为保证服务器安全,上传文件应该放在外界无法直接访问你得目录下,比如放在WEB-INF目录下
- 2.为防止文件覆盖现象的发生,要为文件产生一个唯一的文件名 (添加时间戳 或者 uuid 或者MD5 或者位运算)
- 3.要限制上传文件的大小
- 4.可以限制上传文件的类型,在收到上传文件名时,要判断后缀名是否合格。
需要用到的类详解
- ServletFileUpload 负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象,在使用ServletFileUpload对象解析请求时,需要DiskFileItemFactory对象。所以,我们需要在进行解析工作前构造号DiskFileItemFactory对象,通过ServletFileUpload对象的构造方法,或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性。
工程文件结构
具体实现
package edu.cqupt.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
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 {
String msg = null;
if(!ServletFileUpload.isMultipartContent(req)){ //判断文件是带文件表单还是普通表单
return; //终止运行,说明这一定是一个不带文件的
}
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");//为保证服务器安全,上传文件应该放在外界无法直接访问你得目录下,比如放在WEB-INF目录下
String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp"); // 缓存
File uploadFile = new File(uploadPath);
if(!uploadFile.exists()){
uploadFile.mkdir();
}
File file = new File(tempPath);
if(!file.exists()){
file.mkdir();
}
try {
//1.创建 DiskFileItemFactory
DiskFileItemFactory factory = getDiskFileItemFactory(file);
//2.获取ServletFileUpload
ServletFileUpload upload = getServletFileUpload(factory);
// 3.处理上传文件
msg = uploadParseRequest(upload,req,uploadPath);
} catch (FileUploadException e) {
e.printStackTrace();
}
req.setAttribute("msg",msg); // 请求转发消息
req.getRequestDispatcher("info.jsp").forward(req,resp);
}
public static DiskFileItemFactory getDiskFileItemFactory(File file){
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024*1024); // 缓存区大小为1M
factory.setRepository(file); // 临时目录的保存目录,需要一个file
return factory;
}
public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory){
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setProgressListener(new ProgressListener() {
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("总大小:" + pContentLength + "已上传:" + pBytesRead + "已上传:" + (int)(((double)pBytesRead/(double)pContentLength)*100)+ "%" );
}
});
upload.setHeaderEncoding("UTF-8");
upload.setFileSizeMax(1024*1024*10);
upload.setSizeMax(1024*1024*10);
return upload;
}
public static String uploadParseRequest(ServletFileUpload upload,HttpServletRequest req,String uploadPath) throws FileUploadException, IOException {
String message = null;
List<FileItem> fileItems = upload.parseRequest(req);
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
String name = fileItem.getFieldName();
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 + "]");
String uuidPath = UUID.randomUUID().toString();
String realPath = uploadPath + "/" + uuidPath;
File realPathFile = new File(realPath);
if (!realPathFile.exists()) {
realPathFile.mkdir();
}
InputStream is = fileItem.getInputStream();
FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
is.close();
message = "文件上传成功";
fileItem.delete();
}
}
return message;
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%--通过表单上传文件
get:上传文件有大小限制:5kb
post没有大小限制
--%>
<form action="${pageContext.request.contextPath}/upload.do" method="post" enctype="multipart/form-data">
上传用户:<input type="text" name = "username" ><br/>
<p><input type="file" name = "file1"></p>
<p><input type="file" name = "file2"></p>
<p><input type="submit" value="上传">|<input type="reset" value="重置"></p>
</form>
</body>
</html>
info.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
web.xml
<servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>edu.cqupt.servlet.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/upload.do</url-pattern>
</servlet-mapping>
实验效果
找到这个目录,然后通过文件目录进入