1. 程式人生 > >ASIHTTPRequest系列 三 檔案上傳

ASIHTTPRequest系列 三 檔案上傳

               

五、檔案上傳

1、服務端

檔案上傳需要服務端的配合。我們可在本機搭建tomcat測試環境。關於tomcat在MacOSX下的安裝配置,參考作者另一博文《安裝Tomcat到Mac OSX》。

開啟Eclipse,新建web工程。在其中新建一個ServletUploadServlet:

import java.io.*;

import java.util.*;

importjavax.servlet.ServletException;

importjavax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importorg.apache.commons.fileupload.FileItem;

importorg.apache.commons.fileupload.disk.DiskFileItemFactory;

importorg.apache.commons.fileupload.servlet.ServletFileUpload;

publicclass UploadServletextends HttpServlet {

privatebooleanisMultipart;

private String filePath,title;

privateintmaxFileSize = 500 * 1024;

privateintmaxMemSize = 4 * 1024;

private File file ;

publicvoid init( ){

// web.xmlcontext_param中獲得上傳檔案目錄(/data.

filePath =

getServletContext().getInitParameter("file-upload");

}

publicvoiddoPost(HttpServletRequest request,

HttpServletResponse response)

throws ServletException,java.io.IOException {

// 檢查表單是否帶有

ENCTYPE="multipart/form-data"

isMultipart =ServletFileUpload.isMultipartContent(request);

response.setContentType("text/html");

response.setCharacterEncoding("GBK");

java.io.PrintWriter out = response.getWriter( );

if( !isMultipart ){

out.println("<html>");

out.println("<head>");

out.println("<title>Servlet upload</title>");

out.println("</head>");

out.println("<body>");

out.println("<p>No file uploaded</p>");

out.println("</body>");

out.println("</html>");

return;

}

DiskFileItemFactoryfactory = new DiskFileItemFactory();

// 記憶體最大可快取尺寸

factory.setSizeThreshold(maxMemSize);

// 指定當資料超過記憶體最大可快取尺寸時,臨時檔案的目錄

factory.setRepository(new File(filePath+"temp"));

// 檔案上傳物件

ServletFileUpload upload = new ServletFileUpload(factory);

// 設定檔案上傳最大允許尺寸

upload.setSizeMax( maxFileSize );

try{

out.println("<%@pagecontentType='text/html; charset=GBK'%>");

out.println("<html>");

out.println("<head>");

out.println("<title>Servletupload</title>");

out.println("</head>");

out.println("<body>");

// 獲取multipart/form-data內容,其中每個field被分成不同part

List fileItems = upload.parseRequest(request);

// 列舉每個field

Iterator i = fileItems.iterator();

while ( i.hasNext () )

{

FileItem fi = (FileItem)i.next();

if ( !fi.isFormField() )// 如果fieldFile

{

// 獲取fieldnameid

String fieldName = fi.getFieldName();

String fileName = fi.getName();

// 檔名中文處理

fileName=newString(fileName.getBytes(),"gbk");

out.println("file name:"+fileName+"<br>");

String contentType = fi.getContentType();

boolean isInMemory= fi.isInMemory();

long sizeInBytes= fi.getSize();

// 把上傳資料寫入本地磁碟

if(fileName.lastIndexOf("//") >= 0 ){

file = new File( filePath +

fileName.substring( fileName.lastIndexOf("//"))) ;

}else{

file = new File( filePath +

fileName.substring(fileName.lastIndexOf("//")+1)) ;

}

fi.write( file ) ;

out.println("Uploaded Filename:" + fileName + "<br>");

}else{// 如果fieldForm Field

title=fi.getFieldName();

if(title.equals("title")){

title=new String(fi.get(),"gbk");

out.println("title:"+title+"<br>");

}

}

}

out.println("</body>");

out.println("</html>");

}catch(Exception ex) {

System.out.println(ex);

}

}

publicvoiddoGet(HttpServletRequest request,

HttpServletResponse response)

throws ServletException,java.io.IOException {

thrownew ServletException("GET method used with " +

getClass( ).getName( )+": POSTmethod required.");

}

}

再新建一個upload.jsp頁面作為測試:

<%@page contentType="text/html; charset=GBK" language="java" import="java.util.*"%>

<html>

<head>

<title>fbysss UploadBean 示例</title>

<!--meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"-->

<!--meta http-equiv="Content-Type"content="text/html; charset=gb2312"-->

</head>

<FORM name="form1" METHOD="POST"ACTION="UploadServlet" ENCTYPE="multipart/form-data">

<input name="title" type= "text"value="請選擇檔案">

<p>附件</p>

<p><input name="attach" type="FILE"id="attach" size="50"></p>

<input name="ok" type= "submit"value="提交">

</form>

</html>

選擇一個檔案進行上傳,然後到/data目錄下檢查該檔案是否上傳成功。

2、iPhone客戶端

新建類,選擇UIViewController subclass,並勾上“WithXIB for user interface”,命名為 UploadViewController。

IB 開啟 Xib 檔案,在其中拖入1個 UIToolBar 、1個UIBarButtonItem 和1個 UIWebView、1個UIProgressView:

Xcode中宣告必要的變數和 IBOutlet/IBAction:

#import <UIKit/UIKit.h>

#import "ASIFormDataRequest.h"

#import "ASIHTTPRequest.h"

@interface UploadViewController : UIViewController {

UIBarItem* button;

UIWebView* webView;

UIProgressView* progress;

ASIFormDataRequest *request;

NSURL *url;

}

@property(retain,nonatomic)IBOutlet UIBarItem* button;

@property(retain,nonatomic)IBOutlet UIProgressView* progress;

@property(retain,nonatomic)IBOutlet UIWebView* webView;

-(IBAction)go;

-(void)printBytes:(NSString*)str encoding:(NSStringEncoding)enc;

@end

將所有出口正確地連線到 UpdateController.xib 中,儲存。

開啟MainWindow.xib,拖一個UIViewController進去並將其Identifier改為UpdateController,再將它連線到Window物件的的rootViewController。

編寫 UIButton 的 Touch up inside 事件程式碼如下:

-(IBAction)go{

NSString* s=@"哈哈哈";

url=[NSURLURLWithString:@"http://localhost:8080/test/UploadServlet"];

request = [ASIFormDataRequestrequestWithURL:url];

// 字串使用 GBK 編碼,因為 servlet 只識別GBK

NSStringEncoding enc=CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingMacChineseSimp);

[requestsetStringEncoding:enc];

[selfprintBytes:s encoding:enc];// 列印GBK編碼字元

[requestsetPostValue:s forKey:@"title"];

[requestsetFile:@"/Users/kmyhy/Documents/iphone/Iphone開發介紹.doc"forKey:@"attach"];

[requestsetDelegate:self];

[requestsetDidFinishSelector:@selector(responseComplete)];

[requestsetDidFailSelector:@selector(responseFailed)];

[buttonsetEnabled:NO];

[requeststartSynchronous];

}

-(void)responseComplete{

// 請求響應結束,返回responseString

NSString*responseString = [requestresponseString];

[webViewloadHTMLString:responseStringbaseURL:url];

[buttonsetEnabled:YES];

}

-(void)respnoseFailed{

//請求響應失敗,返回錯誤資訊

NSError *error = [requesterror];

[webViewloadHTMLString:[error description] baseURL:url];

[buttonsetEnabled:YES];

}

-(void)printBytes:(NSString *)strencoding:(NSStringEncoding)enc{

NSLog(@"defaultCStringEncoding:%d",[NSStringdefaultCStringEncoding]);

//根據給定的字元編碼,打印出編碼後的字元陣列

constchar *bytes=[str cStringUsingEncoding:enc];

for (int i=0;i<strlen(bytes);i++){

NSLog(@"%d%X",(i+1),bytes[i]);

}

}

編譯、執行。點選go按鈕,程式執行效果如下: