Android编程使用HTTP协议与TCP协议实现上传文件的方法
本文实例讲述了Android编程使用HTTP协议与TCP协议实现上传文件的方法。分享给大家供大家参考,具体如下:
Android上传文件有两种方式,第一种是基于Http协议的HttpURLConnection,第二种是基于TCP协议的Socket。这两种方式的区别是使用HttpURLConnection上传时内部有缓存机制,如果上传较大文件会导致内存溢出。如果用TCP协议Socket方式上传就会解决这种弊端。
HTTP协议HttpURLConnection
1.通过URL封装路径打开一个HttpURLConnection
2.设置请求方式以及头字段:Content-Type、Content-Length、Host
3.拼接数据发送
示例:
privatestaticfinalStringBOUNDARY="---------------------------7db1c523809b2";//数据分割线
publicbooleanuploadHttpURLConnection(Stringusername,Stringpassword,Stringpath)throwsException{
//找到sdcard上的文件
Filefile=newFile(Environment.getExternalStorageDirectory(),path);
//仿Http协议发送数据方式进行拼接
StringBuildersb=newStringBuilder();
sb.append("--"+BOUNDARY+"\r\n");
sb.append("Content-Disposition:form-data;name=\"username\""+"\r\n");
sb.append("\r\n");
sb.append(username+"\r\n");
sb.append("--"+BOUNDARY+"\r\n");
sb.append("Content-Disposition:form-data;name=\"password\""+"\r\n");
sb.append("\r\n");
sb.append(password+"\r\n");
sb.append("--"+BOUNDARY+"\r\n");
sb.append("Content-Disposition:form-data;name=\"file\";filename=\""+path+"\""+"\r\n");
sb.append("Content-Type:image/pjpeg"+"\r\n");
sb.append("\r\n");
byte[]before=sb.toString().getBytes("UTF-8");
byte[]after=("\r\n--"+BOUNDARY+"--\r\n").getBytes("UTF-8");
URLurl=newURL("http://192.168.1.16:8080/14_Web/servlet/LoginServlet");
HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type","multipart/form-data;boundary="+BOUNDARY);
conn.setRequestProperty("Content-Length",String.valueOf(before.length+file.length()+after.length));
conn.setRequestProperty("HOST","192.168.1.16:8080");
conn.setDoOutput(true);
OutputStreamout=conn.getOutputStream();
InputStreamin=newFileInputStream(file);
out.write(before);
byte[]buf=newbyte[1024];
intlen;
while((len=in.read(buf))!=-1)
out.write(buf,0,len);
out.write(after);
in.close();
out.close();
returnconn.getResponseCode()==200;
}
TCP协议Socket
1.我们可以使用Socket发送TCP请求,将上传数据分段发送
示例:
publicbooleanuploadBySocket(Stringusername,Stringpassword,Stringpath)throwsException{
//根据path找到SDCard中的文件
Filefile=newFile(Environment.getExternalStorageDirectory(),path);
//组装表单字段和文件之前的数据
StringBuildersb=newStringBuilder();
sb.append("--"+BOUNDARY+"\r\n");
sb.append("Content-Disposition:form-data;name=\"username\""+"\r\n");
sb.append("\r\n");
sb.append(username+"\r\n");
sb.append("--"+BOUNDARY+"\r\n");
sb.append("Content-Disposition:form-data;name=\"password\""+"\r\n");
sb.append("\r\n");
sb.append(password+"\r\n");
sb.append("--"+BOUNDARY+"\r\n");
sb.append("Content-Disposition:form-data;name=\"file\";filename=\""+path+"\""+"\r\n");
sb.append("Content-Type:image/pjpeg"+"\r\n");
sb.append("\r\n");
//文件之前的数据
byte[]before=sb.toString().getBytes("UTF-8");
//文件之后的数据
byte[]after=("\r\n--"+BOUNDARY+"--\r\n").getBytes("UTF-8");
URLurl=newURL("http://192.168.1.199:8080/14_Web/servlet/LoginServlet");
//由于HttpURLConnection中会缓存数据,上传较大文件时会导致内存溢出,所以我们使用Socket传输
Socketsocket=newSocket(url.getHost(),url.getPort());
OutputStreamout=socket.getOutputStream();
PrintStreamps=newPrintStream(out,true,"UTF-8");
//写出请求头
ps.println("POST/14_Web/servlet/LoginServletHTTP/1.1");
ps.println("Content-Type:multipart/form-data;boundary="+BOUNDARY);
ps.println("Content-Length:"+String.valueOf(before.length+file.length()+after.length));
ps.println("Host:192.168.1.199:8080");
InputStreamin=newFileInputStream(file);
//写出数据
out.write(before);
byte[]buf=newbyte[1024];
intlen;
while((len=in.read(buf))!=-1)
out.write(buf,0,len);
out.write(after);
in.close();
out.close();
returntrue;
}
搭建服务器,完成上传功能
packagecn.test.web.servlet;
importjava.io.File;
importjava.io.IOException;
importjava.util.List;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.apache.commons.fileupload.FileItem;
importorg.apache.commons.fileupload.FileItemFactory;
importorg.apache.commons.fileupload.disk.DiskFileItemFactory;
importorg.apache.commons.fileupload.servlet.ServletFileUpload;
publicclassLoginServletextendsHttpServlet{
privatestaticfinallongserialVersionUID=1L;
@Override
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
doPost(request,response);
}
@Override
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
booleanisMultipart=ServletFileUpload.isMultipartContent(request);
if(isMultipart)
try{
FileItemFactoryfactory=newDiskFileItemFactory();
ServletFileUploadupload=newServletFileUpload(factory);
List<FileItem>items=upload.parseRequest(request);
Filedir=newFile(request.getSession().getServletContext().getRealPath("/WEB-INF/upload"));
//创建目录
dir.mkdir();
for(FileItemitem:items)
if(item.isFormField())
System.out.println(item.getFieldName()+":"+item.getString());
else{
item.write(newFile(dir,item.getName().substring(item.getName().lastIndexOf("\\")+1)));
}
}catch(Exceptione){
e.printStackTrace();
}
else{
System.out.println(request.getMethod());
System.out.println(request.getParameter("username"));
System.out.println(request.getParameter("password"));
}
}
}
希望本文所述对大家Android程序设计有所帮助。