文件上传要点
- 表单的提交方式: 一定是post方式
- 在表单中要设置
enctype="mutilpart/form-data"
: 以二进制流的方式传递数据给服务器 - 上传文件后,需要对数据进行处理解析,才能够得到源文件
- 有文件上传时,不能使用
getParameter()
来获取属性
chrome上传文件信息:
------WebKitFormBoundaryU9JjAwTdfDT5lMMx
Content-Disposition: form-data; name="name"
char
------WebKitFormBoundaryU9JjAwTdfDT5lMMx
Content-Disposition: form-data; name="photo"; filename="text"
Content-Type: application/octet-stream
today is friday
------WebKitFormBoundaryU9JjAwTdfDT5lMMx--
- servlet处理代码:
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
// 得到页面提交的数据流
InputStream is = req.getInputStream();
//上传文件写入的目录
String path = req.getRealPath("/upload");
System.out.println(path); // 路径为实际路径
System.out.println(req.getParameter("name")); // 获取不到name属性的值
File file = new File(path, "t.txt");
OutputStream os = new FileOutputStream(file);
byte[] buffer = new byte[200];
int length = 0;
while((length = is.read(buffer)) != -1) {
os.write(buffer, 0, length);
}
os.close();
is.close();
}
总结:
- 如果直接提交并写入文件,得到的不是所上传的文件本身,需要对文件进行解析处理
- 有公共的类库来处理文件的解析: apache下的commons-fileupload
使用commons-fileupload来实现文件上传及解析
- 导入commons-fileupload和commons-io jar包
- FileItem对象:
- 用于表示通过post提交的文件或者表单的类型
getName()
: 方法只有文件才能够使用,用于读取文件名称getString()
: 用于读取文件或者表单的内容write()
: 将上传的文件写入到磁盘中
- 创建DiskFileItemFactory对象:
- 用于创建FileItem实例,将较小的文件项目存储到内存;将较大的文件项目存储到磁盘
- 创建ServletFileUpload对象,并且将之前创建的DiskFileItemFactory对象作为参数传入: 用于处理通过
multipart/mixed encoding type
上传的文件 - 完整代码:
@WebServlet("/cupload")
public class CommonsUploadServlet extends HttpServlet{
@Override
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
// 创建磁盘文件工厂
DiskFileItemFactory df = new DiskFileItemFactory();
// 文件上传处理
ServletFileUpload sfu = new ServletFileUpload(df);
String path = req.getRealPath("/upload");
try {
List<FileItem> list = sfu.parseRequest(req); // 返回FileItem类型的list
for(FileItem fi : list) {
if (fi.isFormField()) {
// 普通表单项
System.out.println(fi.getFieldName() + "---" + fi.getName() + "---" + fi.getString());
} else {
// 文件上传项
//System.out.println(fi.getFieldName() + "---" + fi.getName() + "---" + fi.getString());
//存储方法1
// InputStream is = fi.getInputStream();
// File file = new File(path, fi.getName());
// OutputStream os = new FileOutputStream(file);
// byte[] buffer = new byte[200];
// int length = 0;
// while((length = is.read(buffer)) != -1) { // 从is中读取一定字节,并将其存储到buffer中,返回-1代表文件读取结束
// os.write(buffer, 0, length); // 从buffer中,写length个bytes到os中,0代表从buffer[0]开始读取数据并写入
// }
// os.close();
// is.close();
//存储方法2,更加便捷
fi.write(new File(path, fi.getName()));
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}