ASIHTTPRequest系列(三):文件上传

五、文件上传

1、服务端

文件上传需要服务端的配合。我们可在本机搭建tomcat测试环境。关于tomcat在Mac OSX下的安装配置,参考作者另一博文《安装Tomcat到Mac OSX》。

打开Eclipse,新建web工程。在其中新建一个Servlet UploadServlet:

importjava.io.*;

importjava.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;

publicclassUploadServletextendsHttpServlet {

privatebooleanisMultipart;

privateStringfilePath,title;

privateintmaxFileSize= 500 * 1024;

privateintmaxMemSize= 4 * 1024;

privateFilefile;

publicvoidinit( ){

//web.xmlcontext_param中获得上传文件目录(/data.

filePath=

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

}

publicvoiddoPost(HttpServletRequest request,

HttpServletResponse response)

throwsServletException, 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;

}

DiskFileItemFactory factory =newDiskFileItemFactory();

//内存最大可缓存尺寸

factory.setSizeThreshold(maxMemSize);

//指定当数据超过内存最大可缓存尺寸时,临时文件的目录

factory.setRepository(newFile(filePath+"temp"));

//文件上传对象

ServletFileUpload upload =newServletFileUpload(factory);

//设置文件上传最大允许尺寸

upload.setSizeMax(maxFileSize);

try{

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

out.println("<html>");

out.println("<head>");

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

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

out.println("<body>");

//获取multipart/form-data内容,其中每个field被分成不同part

ListfileItems = upload.parseRequest(request);

//枚举每个field

Iteratori = fileItems.iterator();

while( i.hasNext () )

{

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

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

{

//获取fieldnameid

StringfieldName= fi.getFieldName();

String fileName = fi.getName();

//文件名中文处理

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

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

StringcontentType= fi.getContentType();

booleanisInMemory= fi.isInMemory();

longsizeInBytes= fi.getSize();

//把上传数据写入本地磁盘

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

file=newFile(filePath+

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

}else{

file=newFile(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=newString(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)

throwsServletException, java.io.IOException {

thrownewServletException("GET method used with "+

getClass( ).getName( )+": POST method required.");

}

}

再新建一个upload.jsp页面作为测试:

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

<html>

<head>

<title>fbysssUploadBean示例</title>

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

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

</head>

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

<inputname="title"type="text"value="请选择文件">

<p>附件</p>

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

<inputname="ok"type="submit"value="提交">

</form>

</html>

将工程部署到tomcat中,启动tomcat,访问http://localhost:8080/test/upload.jsp,显示界面如下:

ASIHTTPRequest系列(三):文件上传

选择一个文件进行上传,然后到/data目录下检查该文件是否上传成功。

2、iPhone客户端

新建类,选择UIViewController subclass,并勾上“With XIB for user interface”,命名为 UploadViewController。

用IB 打开 Xib 文件,在其中拖入1个 UIToolBar 、1个 UIBarButtonItem 和1个 UIWebView、1个UIProgressView:

ASIHTTPRequest系列(三):文件上传

在Xcode中声明必要的变量和 IBOutlet/IBAction:

#import<UIKit/UIKit.h>

#import"ASIFormDataRequest.h"

#import"ASIHTTPRequest.h"

@interfaceUploadViewController : UIViewController {

UIBarItem*button;

UIWebView*webView;

UIProgressView*progress;

ASIFormDataRequest*request;

NSURL*url;

}

@property(retain,nonatomic)IBOutletUIBarItem* button;

@property(retain,nonatomic)IBOutletUIProgressView* progress;

@property(retain,nonatomic)IBOutletUIWebView* 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

NSStringEncodingenc=CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingMacChineseSimp);

[requestsetStringEncoding:enc];

[selfprintBytes:sencoding:enc];//打印GBK编码字符

[requestsetPostValue:sforKey:@"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:[errordescription]baseURL:url];

[buttonsetEnabled:YES];

}

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

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

//根据给定的字符编码,打印出编码后的字符数组

constchar*bytes= [strcStringUsingEncoding:enc];

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

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

}

}

编译、运行。点击go按钮,程序运行效果如下:

ASIHTTPRequest系列(三):文件上传