JavaWeb-上传&下载

文件上传的限制

1.上传对表单限制

>method必须为post

>enctype="multipart/form-data":表示多部件表单数据

>表单中需要添加文件表单项:<input type="file" name="" />

 

2.上传对Servlet的限制

>ServletInputStream request.getInputStream(); 包含整个请求体

 <form action="${pageContext.request.contextPath }/FileUploadServlet" method="post" enctype="multipart/form-data">
    	用户名:<input type="text" name="username"/><br/>
    	文件1:<input type="file" name="file1"/><br/>
    	文件2:<input type="file" name="file2"/><br/>
    	<input type="submit" value="提交"/>
    </form>

 

                 在jsp页面中,尝试在提交表单中存放普通文本和文件上传。当提交之后,在HttpWatch中抓包可以看出,客户端发送给服务器的信息如下:

普通文本表单可以不设置enctype属性:

>当method="post"时,enctype的默认值为application/x-www-form-urlencoded,表示使用url编码正文

>当method="get"时,enctype的默认值为null,没有正文,就不需要enctype

 

通过httpWatch测试,查看表单的请求数据正文,我们发现请求中只有文件名称,而没有文件内容。也就是说,当表单的enctype不是multipart/form-data时,请求中不包含文件内容,而只有文件的名称,这说明普通文本表单中input:file与input:text没什么区别了。

       通过httpWatch测试,查看表单的请求数据正文部分,发现正文部分是由多个部件组成,每个部件对应一个表单字段,每个部件都有自己的头信息。头信息下面是空行,空行下面是字段的正文部分。多个部件之间使用随机生成的分隔线隔开。

        文本字段的头信息中只包含一条头信息,即Content-Disposition,这个头信息的值有两个部分,第一部分是固定的,即form-data,第二部分为字段的名称。在空行后面就是正文部分了,正文部分就是在文本框中填写的内容。

  文件字段的头信息中包含两条头信息,Content-Disposition和Content-Type。Content-Disposition中多出一个filename,它指定的是上传的文件名称。而Content-Type指定的是上传文件的类型。文件字段的正文部分就是文件的内容。

 

         因为我们上传的文件都是普通文本文件,即txt文件,所以在httpWatch中是可以正常显示的,如果上传的是exe、mp3等文件,那么在httpWatch看到的就是乱码了。

Commons-fileupload(commons-fileupload.jar   commons-io.jar)

     该包会解析request中的上传数据(包括各种请求头的和相应的值),解析后的结果是将表单封装到一个FileItem对象中,只需要调用FileItem的方法就能够获取信息。

上传步骤:

1>创建工厂:DiskFileItemFactory factory = new DiskFileItemFactory();

2>创建解析器:ServletFileUpload sfu = new ServletFileUpload(factory);

3>使用解析器来解析request,得到FileItem集合:List<FileItem> fileItemList = sfu.parseRequest(request);

 

FileItem对象中的方法

>boolean isFormField():是否为普通表单项,如果返回true则为普通表单项,返回falst则为文件表单项

>String getFieldName():返回当前表单项的名称

>String getString(String charset):返回表单项的值(仅是普通表单项时使用)

 

>String getName():返回上传文件的名称

>long getSize():返回上传文件字节数

>InputStream getInputStream():返回上传文件对应的输入流

>void write(File destFile):把上传文件的内容放在指定的文件中

 


		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload sfu = new ServletFileUpload(factory);
		try {
			List<FileItem> fileItemList = sfu.parseRequest(request);
			
			FileItem fi1 = fileItemList.get(0);
			FileItem fi2 = fileItemList.get(1);
			
			System.out.println("普通表单项演示:"+fi1.getFieldName()+"="+fi1.getString("UTF-8"));
			System.out.println("Content-type:"+fi2.getContentType());
			System.out.println("Size:"+fi2.getSize());
			System.out.println("filename:"+fi2.getName());
			
			//保存文件
			File destFile = new File("e:/applicationForm.doc");
			try {
				fi2.write(destFile);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}
	
		
	}
<form action="<c:url value='/UpLoadServlet'/>" method="post" enctype="multipart/form-data">
   
  	 用户名:<input type="text" name="username"/><br/>
 	 家庭经济困难学生认定申请表上传:<input type="file" name="ApplicationForm"/><br/>
 	<input type="submit" value="提交"/>
  
   </form>
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		DiskFileItemFactory dfif = new DiskFileItemFactory(1024*20, new File("F:\\temp"));
		ServletFileUpload fileUpload = new ServletFileUpload(dfif);
		
		try {
			List<FileItem> list = fileUpload.parseRequest(request);
			FileItem fileItem = list.get(1);
			String name = fileItem.getName();
			String savepath = this.getServletContext().getRealPath("/WEB-INF/uploads");
			
			// 保存文件
			fileItem.write(path(savepath, name));
		} catch (Exception e) {
			throw new ServletException(e);
		} 
	}
	
	private File path(String savepath, String filename) {
		// 从完整路径中获取文件名称
		int lastIndex = filename.lastIndexOf("\\");
		if(lastIndex != -1) {
			filename = filename.substring(lastIndex + 1);
		}
		
		// 通过文件名称生成一级、二级目录
		int hCode = filename.hashCode();
		String dir1 = Integer.toHexString(hCode & 0xF);
		String dir2 = Integer.toHexString(hCode >>> 4 & 0xF);
		savepath = savepath + "/" + dir1 + "/" + dir2;
		// 创建目录
		new File(savepath).mkdirs();
		
		// 给文件名称添加uuid前缀
		String uuid = CommonUtils.uuid();
		filename = uuid + "_" + filename;
		
		// 创建文件完成路径
		return new File(savepath, filename);
	}

下载

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值