本文實例講述了Android編程使用HTTP協議與TCP協議實現上傳文件的方法。分享給大家供大家參考,具體如下:
Android上傳文件有兩種方式,第一種是基于Http協議的HttpURLConnection,第二種是基于TCP協議的Socket。 這兩種方式的區別是使用HttpURLConnection上傳時內部有緩存機制,如果上傳較大文件會導致內存溢出。如果用TCP協議Socket方式上傳就會解決這種弊端。
HTTP協議HttpURLConnection
1. 通過URL封裝路徑打開一個HttpURLConnection
2.設置請求方式以及頭字段:Content-Type、Content-Length、Host
3.拼接數據發送
示例:
private static final String BOUNDARY = "---------------------------7db1c523809b2";//數據分割線public boolean uploadHttpURLConnection(String username, String password, String path) throws Exception { //找到sdcard上的文件 File file = new File(Environment.getExternalStorageDirectory(), path); //仿Http協議發送數據方式進行拼接 StringBuilder sb = new StringBuilder(); 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"); URL url = new URL("http://192.168.1.16:8080/14_Web/servlet/LoginServlet"); HttpURLConnection conn = (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); OutputStream out = conn.getOutputStream(); InputStream in = new FileInputStream(file); out.write(before); byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) != -1) out.write(buf, 0, len); out.write(after); in.close(); out.close(); return conn.getResponseCode() == 200;}TCP協議Socket
1.我們可以使用Socket發送TCP請求,將上傳數據分段發送
示例:
public boolean uploadBySocket(String username, String password, String path) throws Exception { // 根據path找到SDCard中的文件 File file = new File(Environment.getExternalStorageDirectory(), path); // 組裝表單字段和文件之前的數據 StringBuilder sb = new StringBuilder(); 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"); URL url = new URL("http://192.168.1.199:8080/14_Web/servlet/LoginServlet"); // 由于HttpURLConnection中會緩存數據, 上傳較大文件時會導致內存溢出, 所以我們使用Socket傳輸 Socket socket = new Socket(url.getHost(), url.getPort()); OutputStream out = socket.getOutputStream(); PrintStream ps = new PrintStream(out, true, "UTF-8"); // 寫出請求頭 ps.println("POST /14_Web/servlet/LoginServlet HTTP/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"); InputStream in = new FileInputStream(file); // 寫出數據 out.write(before); byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) != -1) out.write(buf, 0, len); out.write(after); in.close(); out.close(); return true;}搭建服務器,完成上傳功能
package cn.test.web.servlet;import java.io.File;import java.io.IOException;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileItemFactory;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (isMultipart) try { FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); List<FileItem> items = upload.parseRequest(request); File dir = new File(request.getSession().getServletContext().getRealPath("/WEB-INF/upload")); //創建目錄 dir.mkdir(); for (FileItem item : items) if (item.isFormField()) System.out.println(item.getFieldName() + ": " + item.getString()); else{ item.write(new File(dir,item.getName().substring(item.getName().lastIndexOf("http://")+1))); } } catch (Exception e) { e.printStackTrace(); } else { System.out.println(request.getMethod()); System.out.println(request.getParameter("username")); System.out.println(request.getParameter("password")); } }}希望本文所述對大家Android程序設計有所幫助。
新聞熱點
疑難解答
圖片精選