记得很早之前在直接采用流读取上传文件时遇到如果上传是压缩文件就会被破坏,同时也会有不能获取上传表单中的其他域的值的问题。最近又涉及到上传的需求,对使用的上传组件common-fileupload做一个简单的总结
在common-fileupload中,需要掌握的几个重要接口:
DiskFileItemFactory
FileItemFactory的默认实现,可设置对上传文件实例(FileItem)的各种参数:
1、上传文件保存在内存或硬盘的阀值,默认为10kb
2、上传文件保存的临时路径,默认为System.getProperty("java.io.tmpdir")
可通过构造函数和参数设置
public DiskFileItemFactory(int sizeThreshold, File repository) //临时文件存储路径 public void setRepository(File repository) //存储位置阀值 public void setSizeThreshold(int sizeThreshold)
ServletFileUpload
处理上传请求。最重要的是处理上传form表单中的各个域,这里会处理为fileitem和普通的表单。同时提供了上传请求的参数设置:
// headerencoding upload.setHeaderEncoding("UTF-8"); // 一次请求中上传的所有文件大小 upload.setSizeMax(102400); // 上传的单个文件大小 upload.setFileSizeMax(1024); //以上会抛出SizeLimitExceededException异常 // 处理上传进度 upload.setProgressListener(new ProgressListener() { public void update(long pBytesRead, long pContentLength, int pItems) { } });
FileItem
表示一个multipart/form-data请求中所有的表单域对象实例,包括非file域,可通过isFormField来判断。当然还有比较重要的方法就是write将FileItem写入指定的文件
以下是一些通用的写法:
DiskFileItemFactory factory = new DiskFileItemFactory(); // 设置缓冲区大小 factory.setSizeThreshold(10240); // 设置缓冲区目录 factory.setRepository(new File(tempFilePath)); ServletFileUpload upload = new ServletFileUpload(factory); // 处理编码 upload.setHeaderEncoding("UTF-8"); // 一次请求中上传的所有文件大小 upload.setSizeMax(102400); // 上传的单个文件大小 upload.setFileSizeMax(1024); //以上操作如果上传文件超过指定大小,会抛出SizeLimitExceededException异常 // 处理上传进度 upload.setProgressListener(new ProgressListener() { //pItems当前fileItem、pBytesRead当前fileItem已读取长度、pContentLength当前上传总的长度,即如果是上传多个文件,这里是所有文件的容量,还包括页面中其他域的大小 public void update(long pBytesRead, long pContentLength, int pItems) { } }); //所有表单元素FileItem实例 List<FileItem> items = upload.parseRequest(req); Iterator<FileItem> iterator = items.iterator(); while (iterator.hasNext()) { FileItem fileItem = (FileItem) iterator.next(); if(fileItem.isFormField()){ System.out.println(fileItem.getFieldName()); System.out.println(fileItem.getString("UTF-8")); }else{ fileItem.write(new File(path, fileItem.getName())); } } // 删除缓冲目录 new File(tempFilePath).deleteOnExit();
对一个处理多个上传文件的表单:
<form action="../sa/upload" method="post" enctype="multipart/form-data" name="form1"> <input type="file" name="file1"> <input type="file" name="file2"> <input type="file" name="file3"> <input type="input" name="name"> <input type="submit" name="Submit" value="上传"> </form>
上面的代码会读取到三个文件和两个form表单域。当然如果文件上传不满三个也会抛出异常