JSP 文件上传下载系列之二[Commons fileUpload]
来源:互联网 发布:端口135 139 编辑:程序博客网 时间:2024/06/05 22:34
前言
关于JSP 文件上传的基础和原理在系列一中有介绍到。 这里介绍一个很流行的组件commons fileupload,用来加速文件上传的开发。
官方的介绍是: 让添加强壮,高性能的文件到你的servlet和Web应用程序变得容易。
官方项目地址:
http://commons.apache.org/proper/commons-fileupload/
FileUpload分析request 里的数据, 生成一些独立的上传items. 每一个item都继承自 FileItem 这个接口。
下载导入
1. 可以到 http://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi 这个地址下载最新的版本。
2. 另外还需要下载 commons-io的 jar 包,下载地址:
http://commons.apache.org/proper/commons-fileupload/dependencies.html
在servlet 和portlet中都可以使用FileUpload, 以下以servlet的使用来介绍
分析请求(request)
首先,需要判断request 是否是文件上传的request.
系列一也有提,文件上传的form 必须设置成如下:
<form method="POST" enctype="multipart/form-data" action="fileUploadServlet">
这里有提供一个方法判断request 是否是正确的类型
// Check that we have a file upload requestboolean isMultipart = ServletFileUpload.isMultipartContent(request);
例如这里, 如果form 中移除enctype="multipart/form-data", 返回值就是false 了。
最简单的状况
最简单的使用场景如下:
1. 如果上传的文件足够小的话应该保存在内存中
2. 大的文件应该写到临时文件中
3. 超大的文件上传请求应该不被允许
4. 内存中的文件最大值,允许上传的文件最大尺寸和临时文件目录的接收默认的设置。
看个实例:
// Create a factory for disk-based file itemsFileItemFactory factory = new DiskFileItemFactory();// Configure a repository (to ensure a secure temp location is used)ServletContext servletContext = this.getServletConfig().getServletContext();File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");factory.setRepository(repository);// Create a new file upload handlerServletFileUpload upload = new ServletFileUpload(factory);// Parse the requestList<FileItem> items = upload.parseRequest(request);
更多的控制
也可以进行更多的设置, 看例子
// Create a factory for disk-based file itemsDiskFileItemFactory factory = new DiskFileItemFactory();// Set factory constraintsfactory.setSizeThreshold(yourMaxMemorySize);factory.setRepository(yourTempDirectory);// Create a new file upload handlerServletFileUpload upload = new ServletFileUpload(factory);// Set overall request size constraintupload.setSizeMax(yourMaxRequestSize);// Parse the requestList<FileItem> items = upload.parseRequest(request);
这里设置了最大内存大小,临时文件路径和文件最大值。
设置方式也可以这样:
DiskFileItemFactory factory = new DiskFileItemFactory(yourMaxMemorySize, yourTempDirectory);
处理上传的item
需要再提一下的是: FileUpload 不仅会把一个file 的input 放入一个 FileItem, 一般的Form text input 也会放入一个FileItem.
所以在分析完之后接下来就是如何处理这些FileItem 了。
// Process the uploaded itemsIterator<FileItem> iter = items.iterator();while (iter.hasNext()) { FileItem item = iter.next(); if (item.isFormField()) { processFormField(item); } else { processUploadedFile(item); }}
对于一般的form field 来说(text input), 无非就是取它的name 和value 了。
// Process a regular form fieldif (item.isFormField()) { String name = item.getFieldName(); String value = item.getString(); ...}
对于文件类型的话, 可以
// Process a file uploadif (!item.isFormField()) { String fieldName = item.getFieldName(); String fileName = item.getName(); String contentType = item.getContentType(); boolean isInMemory = item.isInMemory(); long sizeInBytes = item.getSize(); ...}
看是否需要写入到某个文件中:
// Process a file uploadif (writeToFile) { File uploadedFile = new File(...); item.write(uploadedFile);} else { InputStream uploadedStream = item.getInputStream(); ... uploadedStream.close();}
得到文件
// Process a file upload in memorybyte[] data = item.get();...
资源清除
如果使用DiskFileItem, 或者说在处理上传文件之前写入临时文件的话,就要考虑资源清除了。
临时文件不再使用的话,是会自动被删除的。org.apache.commons.io.FileCleaner 这个类会启动一个回收线程。
如果不再需要这个回收线程的话, 可以停止它。 方法是在xml 中加入:
<web-app> ... <listener> <listener-class> org.apache.commons.fileupload.servlet.FileCleanerCleanup </listener-class> </listener> ...</web-app>
创建一个 DiskFileItemFactory
FileCleanerCleanup提供了一个org.apache.commons.io.FileCleaningTracker的实例,如果创建一个org.apache.commons.fileupload.disk.DiskFileItemFactory则需要这个实例。像
public static DiskFileItemFactory newDiskFileItemFactory(ServletContext context, File repository) { FileCleaningTracker fileCleaningTracker = FileCleanerCleanup.getFileCleaningTracker(context); DiskFileItemFactory factory = new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, repository); factory.setFileCleaningTracker(fileCleaningTracker); return factory;}
与病毒扫描软件的问题
病毒扫描软件可能会导致FileUpload 的一些异常状况。
解决方式就是让扫描软件不要监视某些特定的目录。
查看上传进度
//Create a progress listenerProgressListener progressListener = new ProgressListener(){ public void update(long pBytesRead, long pContentLength, int pItems) { System.out.println("We are currently reading item " + pItems); if (pContentLength == -1) { System.out.println("So far, " + pBytesRead + " bytes have been read."); } else { System.out.println("So far, " + pBytesRead + " of " + pContentLength + " bytes have been read."); } }};upload.setProgressListener(progressListener);
或者
//Create a progress listenerProgressListener progressListener = new ProgressListener(){ private long megaBytes = -1; public void update(long pBytesRead, long pContentLength, int pItems) { long mBytes = pBytesRead / 1000000; if (megaBytes == mBytes) { return; } megaBytes = mBytes; System.out.println("We are currently reading item " + pItems); if (pContentLength == -1) { System.out.println("So far, " + pBytesRead + " bytes have been read."); } else { System.out.println("So far, " + pBytesRead + " of " + pContentLength + " bytes have been read."); } }};
Streaming API
上面提到的API (传统API) 是在使用前完全把Item 读到某个地方(内存或是文件),使用Streaming 的话,可以逐步的读取, 性能和内存使用都会大大提升。
// Create a new file upload handlerServletFileUpload upload = new ServletFileUpload();// Parse the requestFileItemIterator iter = upload.getItemIterator(request);while (iter.hasNext()) { FileItemStream item = iter.next(); String name = item.getFieldName(); InputStream stream = item.openStream(); if (item.isFormField()) { System.out.println("Form field " + name + " with value " + Streams.asString(stream) + " detected."); } else { System.out.println("File field " + name + " with file name " + item.getName() + " detected."); // Process the input stream ... }}
- JSP 文件上传下载系列之二[Commons fileUpload]
- 文件上传下载之commons-fileupload
- commons-fileupload上传下载文件
- commons-fileupload实现文件上传下载
- 文件上传之 commons-fileupload(二)
- 文件上传之 commons-fileupload(二)
- 文件上传下载之FileUpload
- JSP文件上传下载+FileUpload学习
- 使用commons-fileupload组件上传下载文件
- commons-fileupload上传下载
- commons-fileupload上传下载
- JSP用common-fileupload实现文件上传下载
- JSP使用commons-fileupload实现文件上传
- JSP 文件上传组件commons-fileupload
- Jsp 使用commons-fileupload实现文件上传
- 用jsp+commons-fileupload实现文件上传
- JavaWeb实现文件上传下载功能实例解析------apache.commons.fileupload
- 文件上传之 commons-fileupload(一)
- python测试框架及应用
- ABAP 程序中退出操作(CHECK, EXIT, RETURN, LEAVE PROGRAM...)
- java基础之Integer和Long对象相等比较 .
- 【原始对偶费用流ver2.0】hdu4744
- Linux的运行模式
- JSP 文件上传下载系列之二[Commons fileUpload]
- cocos2d-x面试题
- HIVE再次尝试 用 Mysql 环境搭建 以及 mysql中文乱码完美解决
- VC++ 求绝对值函数abs、labs和fabs介绍
- 关于IN UPDATE TASK
- VT码
- silverlight中文不能输入问题
- 如何判断系统中是否安装了某种字体
- [设计模式笔记]二. 结构型模式--13.Proxy模式(代理模式)(一)