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程序设计有所帮助。