风行天下

JAVA太极
posts - 4, comments - 10, trackbacks - 0, articles - 55
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Jakarta Commons FileUpload

Posted on 2005-04-04 11:20 风太少 阅读(735) 评论(0)  编辑  收藏
SECTION 01 FileUpload 总览

在编写网站程序的时候, client 与 server 之间的往往不只有纯文字的沟通, 还会有 binary 的文件传输, 该如何在 HTML Form 之中传送, 就要遵守 RFC 1867 的规范了.

基本上, post.jsp (选择文件)应该都会有下面类似的 html tag :


<form action="upload.jsp"  enctype="multipart/form-data"  method="POST">
	input your name: <input type="text" name="name"> <br>
	select the file: <input type="file" name="file"> <br>
	<input type="submit" value="submit">
</form>

这一部份是属于 HTML 的范畴, 有兴趣的可以钻研 RFC ...



SECTION 02 multipart/form-data 的 HTTP 表现情形

当你按下传送的时候, Browser 将会送出 Post 的资料到 server,

POST http://localhost:9000/fileupload/upload.jsp HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*
Referer: http://localhost:9000/fileupload/post.jsp
Accept-Language: zh-tw,zh-cn;q=0.7,en-us;q=0.3
Content-Type: multipart/form-data; boundary=---------------------------7d33e580784
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Host: www.softleader.com.tw
Content-Length: 3020
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=3B31F07F56328E7B623A9BA1C4E3479D
我们可以知道, Contenet-Type 是用 multipart/form-data 另外还有 boundary 的传输.


SECTION 03 实际的例子 File.html by 林上杰






<html>
<head>
<title>File Upload</title>
<meta http-equiv="Content-Type" content="text/html; charset=big5">
</head>
<body bgcolor="#FFFFFF" text="#000000"><p><font size="5"color="#FF0000">
<b>第七章 文件上传范例</b></font></p>

<form name="Form1" enctype="multipart/form-data" method="post" action="JYFile.jsp"> 
<p>上传文件 1: <input type="file"name="File1" size="20" maxlength="20"> </p>
<p>文件1叙述: <input type="text" name="File1" size="30" maxlength="50"> </p>
<p>上传文件 2: <input type="file" name="File2" size="20" maxlength="20"> </p>
<p>文件2叙述: <input type="text" name="File2" size="30" maxlength="50"> </p>
<p>上传文件3: <input type="file" name="File3" size="20" maxlength="20"> </p>
<p>文件3叙述: <input type="text" name="File3" size="30" maxlength="50"> </p>
<p> <input type="submit"value="上传"> <input type="reset" value="清除"> </p>
</form>

</body>
</html>




SECTION 04 传送格式

 
POST /newspaper/JYFile.jsp HTTP/1.1

Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*

Referer: http://localhost:9000/newspaper/JYFile.html

Accept-Language: zh-tw,zh-cn;q=0.7,en-us;q=0.3

Content-Type: multipart/form-data; boundary=---------------------------7d31091c6205fc

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)

Host: localhost:9000

Content-Length: 428583

Connection: Keep-Alive

Cache-Control: no-cache

Cookie: JSESSIONID=E141744815A8FF44F8AA9BA6D5946710



-----------------------------7d31091c6205fc

Content-Disposition: form-data; name="File1"; filename="C:\test\测试.exe"

Content-Type: application/octet-stream


XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ( binary 乱码 )

-----------------------------7d31091c6205fc

Content-Disposition: form-data; name="File1"



exe

-----------------------------7d31091c6205fc

Content-Disposition: form-data; name="File2"; filename="C:\test\测试.gif"

Content-Type: image/gif


XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ( binary 乱码 )

-----------------------------7d31091c6205fc

Content-Disposition: form-data; name="File2"



gif

-----------------------------7d31091c6205fc

Content-Disposition: form-data; name="File3"; filename="C:\test\测试.xls"

Content-Type: application/vnd.ms-excel


XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ( binary 乱码 )


-----------------------------7d31091c6205fc

Content-Disposition: form-data; name="File3"



xls

-----------------------------7d31091c6205fc--




SECTION 05 送到 JYFile.jsp 上传处理 by JiaYun



<%@ page contentType="text/html;charset=Big5" language="java" %>
<%@ page import="java.io.*" %>
<%@ page import="java.util.*" %>
<%@ page import="org.apache.commons.fileupload.*" %>

<% 
	// 申明将上传文件放到服务器的 / .... /upload 目录中 
    String saveDirectory = "c:\\";
    // 申明临时目录
    String tmpDirectory = "c:\\";
    // 申明限制上传文件总大小为, 单位为 byte, -1 表示无限制
    int maxPostSize = 1024 * 1024; 
%>
<%
    // 申明储存叙述上传文件内容的变量	
    String FileDescription = null; 
    // 申明储存上传文件名称的变量
    String FileName = null;
    // 申明储存上传文件大小的变量
    long FileSize = 0;
    // 申明储存上传文件类型的变量
    String ContentType = null;
    // 计算上传文件之个数
    int count = 0 ;
%>

<%	
    DiskFileUpload upload = new DiskFileUpload();
    
    // 设置内存存放数据的大小, 超过则写入文件, 有设定临时目录, 临时文件置于临时目录下
    upload.setSizeThreshold(4096);
    
    // 设置总上传大小限制
    upload.setSizeMax(maxPostSize);
    
    // 设置临时目录
    upload.setRepositoryPath(tmpDirectory);
    List /* FileItem */ items = upload.parseRequest(request);
%>
<body>
<% 
	Iterator iter = items.iterator();
	
    int tmp = 0;
    FileItem tmpItem = null;
	while (iter.hasNext()) 
	{ 
        tmp++;
        FileItem item = (FileItem) iter.next();
        
        if (item.isFormField()) {
        // 如果是一般栏位, 取得文件叙述
        
            FileDescription = item.getString();
            
        } else {
        // 否则取得文件信息
        
            FileName = item.getName();
			
		// 因为不同的浏览器会造成传递 path + filename, 有些则只有 filename
  try {
   // for wintel platform
    FileName = FileName.substring(FileName.lastIndexOf("\\")+1);
	 // for unix-like platform
    FileName = FileName.substring(FileName.lastIndexOf("/")+1); 
  } catch ( Exception ex ) {
	out.println(ex);
  }


            ContentType = item.getContentType();
            FileSize = item.getSize();
            tmpItem = item;        
        }
        
        // 因为一个文件都是两个栏位, 每读取两个栏位处理一次
		if (tmp == 2 && FileSize != 0)
		{ 
			count ++;

%>
<font color="red">你上传的第<%= count %>个的文件:</font><br>
文件名称为:<%= FileName %><br>
文件大小为:<%= FileSize %> Bytes<br>
文件类型为:<%= ContentType %><br>
文件的叙述:<%= FileDescription %><br><br>

<%
           // 将文件写入存档目录
   try {
      out.println(FileName);
      File uploadedFile = new File(saveDirectory + FileName);
      tmpItem.write(uploadedFile);
   } catch ( Exception ex ) {
      out.println(ex);
    }
            
            tmp = 0;
        } else if (tmp == 2 && FileSize == 0) {
            tmp = 0;
		} // end if 
	} // end while
%> 
您总共上传<font color="red"><%= count %></font>个文件
</body>
</html>






家芸妹妹把注解说明的很清楚了, 有心的人就仔细查阅吧 ~~~


SECTION 06 Struts FileUpload

为何 struts 1.1 要等 Commons-FileUpload 1.0 呢



因为 struts 有一个 subpackage 叫做 org.apache.struts.upload.*; 这里面就是设定相关的 file 格式如果你使用 struts 为 MVC Framework 就可以参考 example 中的 struts-upload.war 的开发



(1) 建立 upload.jsp

<html:form action="upload.do?queryParam=Successful" enctype="multipart/form-data">
文件叙述:<html:text property="theText" /><br>
选择文件:<html:file property="theFile" /><br>
</html:form>




(2) 建立 UploadForm.java

public class UploadForm extends ActionForm{
	..........     
	public String getTheText() {
		return theText;    
	}    
	public void setTheText(String theText) {        
		this.theText = theText;    
	}    
	public FormFile getTheFile() {        
		return theFile;    
	}    
	public void setTheFile(FormFile theFile) {
		this.theFile = theFile;
	}
	..........
}
请注意 FormFile 是建立在 org.apache.struts.upload 这个 package 中的



(3) 编写 UploadAction

public ActionForward execute(ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response){
	UploadForm theForm = (UploadForm) form;
	String text = theForm.getTheText();
	FormFile file = theForm.getTheFile();
	String fileName= file.getFileName();
	String contentType = file.getContentType();
	String size = (file.getFileSize() + " bytes");
	.... // 看你要如何处理
	.... // 可以用 InputStream 取得 file.getInputStream 等等
	return mapping.findForward("ThePageYouWannaGo");
}




(4) 建立 struts-config.xml

  <form-beans>    
  <form-bean name="uploadForm" 
        type="org.apache.struts.webapp.upload.UploadForm" />  
  </form-beans>  
  <action-mappings>    
  <!-- Upload Action -->    
  <action path="/upload" type="org.apache.struts.webapp.upload.UploadAction" 
        name="uploadForm" scope="request" input="/upload.jsp">        
  <forward name="display" path="/display.jsp" />   
  </action>
详细内容请下载 struts 1.1 src 查阅内容


SECTION 06 总结

其实大家熟悉的都是 Oreilly MultiPartRequest 和 jspsmart的SmartUpload , 请参考 jsptw 的 browser 所写的著作. JSPtw 相关讨论

只有注册用户登录后才能发表评论。


网站导航: