servlet利用DiskFileItemFactory实现文件上传

DiskFileItemFactory

DiskFileItemFactory 是创建FileItem 对象的工厂,这个工厂类常用方法:
1、public void setSizeThreshold(int sizeThreshold) :设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时,fileupload组件将使用临时文件缓存上传文件。
2、public void setRepository(Java.io.File repository) :指定临时文件目录,默认值为System.getProperty(“java.io.tmpdir”).
3、public DiskFileItemFactory(int sizeThreshold,java.io.File repository) :构造函数

ServletFileUpload

ServletFileUpload 负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem 对象中。常用方法有:
1、boolean isMultipartContent(HttpServletRequest request) :判断上传表单是否为multipart/form-data类型

2、List parseRequest(HttpServletRequest request):解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合。

3、setFileSizeMax(long fileSizeMax) :设置上传文件的最大值(单个文件),用于设置单个上传文件的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字。

4、setSizeMax(long sizeMax) :设置上传文件总量的最大值(所有上传文件),用于设置请求消息实体内容(即所有上传数据)的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字。

5、setHeaderEncoding(java.lang.String encoding) :设置编码格式。在文件上传请求的消息体中,除了普通表单域的值是文本内容以外,文件上传字段中的文件路径名也是文本,在内存中保存的是它们的某种字符集编码的字节数组,Apache文件上传组件在读取这些内容时,必须知道它们所采用的字符集编码,才能将它们转换成正确的字符文本返回。

FileItem

FileItem类的常用方法:
1、boolean isFormField(): isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false。

2、 String getName()
用于获得文件上传字段中的文件名。注意IE或FireFox中获取的文件名是不一样的,IE中是绝对路径,FireFox中只是文件名。

3、String getFieldName()
用于返回表单标签name属性的值。

4、 void write(File file):用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。

5、 String getString():用于将FileItem对象中保存的数据流内容以一个字符串返回,它有两个重载的定义形式:
public Java.lang.String getString();
public java.lang.String getString(java.lang.String encoding) throws java.io.UnsupportedEncodingException
前者使用缺省的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码将主体内容转换成字符串。如果在读取普通表单字段元素的内容时出现了中文乱码现象,请调用第二个getString方法,并为之传递正确的字符集编码名称。

6、 void delete():delete方法用来清空FileItem类对象中存放的主体内容,如果主体内容被保存在临时文件中,delete方法将删除该临时文件。尽管当FileItem对象被垃圾收集器收集时会自动清除临时文件,但及时调用delete方法可以更早的清除临时文件,释放系统存储资源。

InputStream

InputStream常用方法
1、read() : 从输入流中读取数据的下一个字节,返回0到255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回-1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。

2、read(byte[] b) : 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在 b 中。

实现步骤:
1、创建DiskFileItemFactory对象,设置缓冲区大小和临时文件目录。
2、使用DiskFileItemFactory 对象创建ServletFileUpload对象,并设置上传文件的大小限制。
3、调用ServletFileUpload.parseRequest方法解析request对象,得到一个保存了所有上传内容的List对象。
4、对list进行迭代,每迭代一个FileItem对象,调用其isFormField方法判断是否是上传文件:
4.1、 为普通表单字段,则调用getFieldName、getString方法得到字段名和字段值。
4.2、为上传文件,则调用getInputStream方法得到数据输入流,从而读取上传数据。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadPhotoServlet extends HttpServlet{
	public void doPost(HttpServletRequest request, HttpServletResponse response) {
		String filename = null;
		try {
			DiskFileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			//设置上传文件的大小限制为1M
			factory.setSizeThreshold(1024 * 1024);
			List items = null;
			try {
				items = upload.parseRequest(request);
			}catch(FileUploadException e) {
				e.printStackTrace();
			}
			Iterator iter = items.iterator();
			while(iter.hasNext()) {
				FileItem item = (FileItem)iter.next();
				//item.isFormField()判断上传的是不是文件,如果是文件返回false,不是返回true
				if(!item.isFormField()) {
					//根据时间戳创建头像文件
					filename = System.currentTimeMillis() + ".jpg";
					//通过getRealPath获取上传文件,文件会获取到项目web目录下的uploaded中
					String photoFolder = request.getServletContext().getRealPath("uploaded");
					File f = new File(photoFolder,filename);
					f.getParentFile().mkdirs();
					//通过item.getInputStream()获取浏览器上传的输入流
					InputStream is = item.getInputStream();
					//复制文件
					FileOutputStream fos = new FileOutputStream(f);
					byte b[] = new byte[1024 * 1024];
					int length = 0;
					while((length = is.read(b)) != -1) {
						fos.write(b,0,length);
					}
					fos.close();
				}else {
					//普通输入项,得到input中的name属性的值
					String name = item.getFieldName();
					//得到输入项中的值
					String value = item.getString("UTF-8");
					System.out.println("name=" + name + " value=" + value);
				}
			}
			String html = "<img width='200' height='150' src='uploaded/%s' />";
			response.setContentType("text/html");
			PrintWriter pw = response.getWriter();
			pw.format(html, filename);
			
		}catch(FileNotFoundException e) {
			e.printStackTrace();
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值