《Java》----详解用apache的commons-fileupload组件实现文件上传

   在web开发中,文件上传功能是很普遍的,我们最常见的就是上传图片了,还有上传Excel,今天小编给大家分享一下利用apache的组件实现文件上传功能。

   文件上传总体思路

   我们想要将磁盘上的文件上传到服务器上去,首先应该有一个管理磁盘文件的工具,当我们上传文件时,还要有一个负责上传文件和解析文件的工具,这两个工具就是apache提供的jar包,commons-fileupload组件和commons-io组件。我们将这两个组件放到我们的项目中,这样我们就可以开始上传工作了。小编将上传工作分成了三个步骤,1.准备需要上传的磁盘文件,2.开始上传,3.解析上传文件并保存到服务器。

   一.准备需要上传的磁盘文件

   文件准备就不用说了,先建立一个jsp,此jsp负责用户上传文件。此jsp中有一form表单,此表单有三个特点,或者是说文件上传的三个前提。

   a、表单的method必须是post

    b、表单的enctype属性必须是multipart/form-data

    c、表单中提供<inputtype="file"/>类型的上传输入域

   下面是具体的代码:
<form action="${pageContext.request.contextPath}/servlet/UploadServlet2" method="post" enctype="multipart/form-data">
    	name:<input type="text" name="name"/><br/>
    	 file1:<input type="file" name="photo"/><br/>
    	file2:<input type="file" name="photo"/><br/>
    	<input type="submit" value="上传"/>
    </form>

   二.开始上传

   我们建立一个servlet,在此servlet中开始准备上传时用到的类,也就是DiskFileItemFactory类,和ServletFileuqLoad类,DiskFileItemFactory负责管理磁盘文件,ServletFileuqLoad类负责上传和解析文件。下面是具体的代码。

<pre name="code" class="java">public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");// 解决上传的中文文件乱码问题
		response.setContentType("text/html;charset=UTF-8");
		// 1.0. 检查是否是multipart/form-data类型的
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		if (!isMultipart) {
			throw new RuntimeException(
					"The form's enctype attribute value must be multipart/form-data");
		}

		// 2.0开始实现上传,创建上传文件需要用到的两个对象
		DiskFileItemFactory factory = new DiskFileItemFactory();// 产生FileItem的工厂
		ServletFileUpload sfu = new ServletFileUpload(factory); //因为解析器依赖于这个工厂,所以将这个工厂传进去

		// 3.0创建一个容器来接收解析的内容
		List<FileItem> items = new ArrayList<FileItem>();
		
		//4.0将上传的文件信息放到容器中
		try {
			items = sfu.parseRequest(request);
		}  catch (FileUploadException e) {
			e.printStackTrace();
		}

		//5.0  遍历  开始处理解析的内容,这里封装了两个方法,一个是专门处理FormField的方法,一个是专门处理UploadField的方法
		for (FileItem item : items) {
			if (item.isFormField()) {
				processFormField(item);// 处理普通p上传字段
			} else {
				processUploadField(item);// 处理上传字段
			}
			
		}

	}


      public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);

    }

 

  下面是两个需要解析的方法,一个是一个是专门处理FormField的方法(也就是表单中普通的字段),一个是专门处理UploadField的方法(也就是需要上传的文件)。

  三、解析上传文件并保存到服务器

   1、专门处理FormField的方法

<pre name="code" class="java">protected void processFormField(FileItem item) {
		// 打印到控制台
		String fieldName = item.getFieldName();
		String value = "";
		try {
			value = item.getString("UTF-8");// 解决普通字段的编码问题,得到普通字段的值
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		System.out.println(fieldName + "=" + value);
	}
 

   2、专门处理FormField的方法(此方法负责存放文件)

<pre name="code" class="java">protected void processUploadField(FileItem item) {
		try {

			// 找到一个存放位置 存放文件名
			String fileName = item.getName();// 上传的文件的文件名
												// C:\Users\wzhting\Desktop\a.txt
												// a.txt(浏览器不同)
			if (fileName != null) {
				// 控制只能能上传图片
				// if (!item.getContentType().startsWith("image")) {
				// return;
				// }
				fileName = FilenameUtils.getName(fileName);
				fileName = IdGenertor.genGUID() + "_" + fileName;
			}

			// 存放路径
			String realPath = getServletContext().getRealPath("/WEB-INF/files");

			// 生成一个子目录
			String childDirectory = genChildDirectory(realPath, fileName);
			File storeDirectory = new File(realPath + File.separator
					+ childDirectory);
			//如果目录不存在,就创建一个
			if (!storeDirectory.exists()) {
				storeDirectory.mkdirs();
			}
			//开始存放磁盘文件
			item.write(new File(storeDirectory, fileName));
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
 
   3、为了避免上传的文件存在同一个文件夹下(对于后期的遍历查找不利)我们可以写一个方法来临时创建分目录。 

<pre name="code" class="java">// 按照hashcode创建分目录 放置一个文件夹下面的上传文件过度
	private String genChildDirectory(String realPath, String fileName) {
		int hashCode = fileName.hashCode();
		int dir1 = hashCode & 0xf;
		int dir2 = (hashCode & 0xf0) >> 4;
		String str = dir1 + File.separator + dir2;
		File file = new File(realPath, str);
		if (!file.exists()) {
			file.mkdirs();
		}
		return str;

	}

	// 按照时间创建分目录 放置一个文件夹下面的文件过多
	protected String genChildDirectory(String realPath) {
		Date now = new Date();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String str = df.format(now);

		File file = new File(realPath, str);
		if (!file.exists()) {
			file.mkdirs();
		}
		return str;
	}
 
   上面两个方法一个是根据日期来创建目录,一个是根据hashcode创建目录。 

   四、其它上传文件中经常用到的功能

   1.限制上传文件的类型,比如说,限制只能上传照片

 
 

if (!item.getContentType().startsWith("image")) {
	return;
 }

   2.限制一下上传文件的大小

DiskFileItemFactory factory = new DiskFileItemFactory();// 产生FileItem的工厂
		ServletFileUpload sfu = new ServletFileUpload(factory); //因为解析器依赖于这个工厂,所以将这个工厂传进去
		// 限制上传文件大小
		sfu.setFileSizeMax(1024 * 196);// 限制单个文件的大小不超过200kb
		//sfu.setSizeMax(5*1024*1024);//限制上传的总文件大小不超过5M
		// 3.0创建一个容器来接收解析的内容
		List<FileItem> items = new ArrayList<FileItem>();
		//4.0将上传的文件信息放到容器中
		try {
			items = sfu.parseRequest(request);
		} catch (FileUploadBase.FileSizeLimitExceededException e) {
			response.getWriter().write("照片不能超过196k");
		} catch (FileUploadException e) {
			e.printStackTrace();
		}

  五、小结

  小编将上传文件的步骤和代码总结了一遍,其实当文件上传到服务器上的时候,我们有时候还需要将文件的存放路径放在数据库中,这样以来我们再取改文件的时候就相对容易一点了。整个文件上传的过程,我认为在文件解析和存储的过程是最麻烦的,里面用到了IO的许多知识,好了,就总结到这吧!

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
commons-fileupload是一个用于处理文件上传Java类库。它提供了简单易用的API,可以用于实现文件上传功能。要使用commons-fileupload,你需要进行以下步骤: 1. 导入commons-fileupload库:下载commons-fileupload库的jar件,并将其添加到你的项目中。 2. 创建Servlet或Controller类:创建一个处理文件上传的Servlet或Controller类。 3. 创建DiskFileItemFactory对象:使用DiskFileItemFactory类创建一个件项工厂对象,设置临时件存储路径和内存缓冲区大小。 4. 创建ServletFileUpload对象:使用ServletFileUpload类创建一个文件上传对象,并设置文件上传的大小限制和字符编码。 5. 解析请求:使用ServletFileUpload对象的parseRequest()方法解析请求,得到FileItem对象的列表。 6. 处理件:遍历FileItem对象的列表,对每个件项进行处理。你可以判断件项是否是普通字段还是件,以及获取字段名称、件名、件大小等信息。 以下是一个简单的示例代码: ```java import org.apache.commons.fileupload.*; import org.apache.commons.fileupload.disk.*; import org.apache.commons.fileupload.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; public class FileUploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); try { List<FileItem> items = upload.parseRequest(request); for (FileItem item : items) { if (item.isFormField()) { // 处理普通字段 String fieldName = item.getFieldName(); String fieldValue = item.getString(); // ... } else { // 处理件 String fieldName = item.getFieldName(); String fileName = item.getName(); long fileSize = item.getSize(); // ... } } // 文件上传成功 response.getWriter().println("文件上传成功!"); } catch (FileUploadException e) { // 文件上传失败 response.getWriter().println("文件上传失败!"); } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值