在千锋“逆战”学习第十七天,王金涛
努力到无能为力,拼搏到感动自己!
文件上传三要素:
①表单提交方式为post
②表单中需要文件上传项
③enctype=multipart/form-data
代码实现三部走:
1,导入jar包:
2.文件上传项
3.编写Servlet
创建磁盘文件项工厂对象DiskFileItemFactory
创建核心解析类ServletFileUpload
解析请求,获取到所有的文件项
import com.qfedu.bean.MyFile;
import com.qfedu.service.FileService;
import com.qfedu.service.FileServiceImpl;
import org.apache.commons.fileupload.FileItem;
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;
//1,自定义类继承HttpServlet
public class UploadServlet extends HttpServlet {
//2,重写doGet及doPost
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//中文文件名称可以解决中文乱码
// req.setCharacterEncoding("utf-8");
System.out.println("文件上传");
//1,创建磁盘文件项工厂对象
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
//2,获取核心解析对象
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
//解决中文文件乱码问题!!!
servletFileUpload.setHeaderEncoding("utf-8");
try {
//3,解析请求 ,获取"文件数据"(文件项集合)
List<FileItem> fileItems = servletFileUpload.parseRequest(req);
String description = null;
String fileName = null;
for (FileItem fileItem : fileItems) {
//4,获取每一个文件项 . 文字描述/文件数据
if (fileItem.isFormField()) {
//文字描述:打印出文字描述
//问题1:文字描述中文乱码问题
description = fileItem.getString("utf-8");
System.out.println(description);
} else {
//文件数据 : 在fileItem中,以输入流形式存在
InputStream inputStream = fileItem.getInputStream();
//高效字节输入流 : 读取数据
BufferedInputStream bis = new BufferedInputStream(inputStream);
//高效字节输出流 : 写出数据
//path:文件上传的路径(服务器) --> 在tomcat中新建一个upload文件夹,存储上传文件的!!!
//upload文件夹对应的服务器路径
String dirPath = req.getServletContext().getRealPath("upload");
System.out.println(dirPath);
File dir = new File(dirPath);
if (!dir.exists()) {
dir.mkdir();
}
//文件名称
//当前时间毫秒值 / UUID
fileName = System.currentTimeMillis() + "-" + fileItem.getName();
String path = dirPath + File.separator + fileName;
//idea如何部署web工程!!!
System.out.println(path);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path));
//边读边写
int len = -1;
byte[] bys = new byte[8192];
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bis.close();
bos.close();
//文件上传成功后,操作数据库,将文件信息(id,文件名称,描述信息,文件访问路径)添加到数据库中
//DbUtils:JDBC工具类,apache
//c3p0:连接池
//mysql:驱动jar包
}
}
FileService fileService = new FileServiceImpl();
// http://localhost:8080/day16/upload/文件名称.txt
MyFile myFile = new MyFile(1, fileName, description, req.getContextPath() + File.separator + "upload" + File.separator + fileName);
fileService.upload(myFile);
//转发跳转到FileListServlet资源,作用是获取文件列表信息
req.getRequestDispatcher("fileList").forward(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
文件上传API:
ServletFileUpload:核心解析类
parseRequest(HttpServletRequest request):解析请求,并获取相关文件项 setHeaderEncoding(String encoding):解决中文文件名乱码
FileItem:文件项
boolean isFormField() 返回为true,普通字段。返回为false,就是文件。
String getFieldName() 获取表单字段
String getString(String encoding) 根据指定编码格式获取字段值
String getName() 获取上传文件名称
InputStream getInputStream() 获取上传文件对应的输入流
上传文件名称重复问题