折騰了好幾天的 HTTP 終於搞定了,經測試正常,不過是初步用例測試用的,因為後面還要修改先把目前的版本儲存在部落格裡吧。
其中POST因為涉及多段上傳需要匯入兩個包檔案,我用的是最新的 httpmine4.3 發現網上很多 MultipartEntity 相關的文章都是早起版本的,以前的一些方法雖然還可用,但新版本中已經不建議使用了,所以全部使用新的方式 MultipartEntityBuilder 來處理了。
httpmime-4.3.2.jar httpcore-4.3.1.jar
如果是 android studio 這裡可能會遇到一個問題:Android Duplicate files copied in APK
經測試 POST 對中文處理也是正常的,沒有發現亂碼
下面是完整代碼:
ZHttpRequest.java
package com.ai9475.util;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.client.methods.HttpRequestBase;import org.apache.http.entity.ContentType;import org.apache.http.entity.mime.HttpMultipartMode;import org.apache.http.entity.mime.MultipartEntityBuilder;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.params.BasicHttpParams;import org.apache.http.params.HttpConnectionParams;import org.apache.http.params.HttpParams;import org.apache.http.protocol.HTTP;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.nio.charset.Charset;import java.util.Iterator;import java.util.Map;import java.util.Set;/** * Created by ZHOUZ on 14-2-3. */public class ZHttpRequest{ protected String url = ; protected Map headers = null; protected int connectionTimeout = 5000; protected int soTimeout = 10000; protected int statusCode = 200; protected String charset = HTTP.UTF_8; protected HttpGet httpGet; protected HttpPost httpPost; protected HttpParams httpParameters; protected HttpResponse httpResponse; protected HttpClient httpClient; protected String inputContent; /** * 設定當前請求的連結 * * @param url * @return */ public ZHttpRequest setUrl(String url) { this.url = url; return this; } /** * 佈建要求的 header 資訊 * * @param headers * @return */ public ZHttpRequest setHeaders(Map headers) { this.headers = headers; return this; } /** * 設定連線逾時時間 * * @param timeout 單位(毫秒),預設 5000 * @return */ public ZHttpRequest setConnectionTimeout(int timeout) { this.connectionTimeout = timeout; return this; } /** * 設定 socket 讀取逾時時間 * * @param timeout 單位(毫秒),預設 10000 * @return */ public ZHttpRequest setSoTimeout(int timeout) { this.soTimeout = timeout; return this; } /** * 設定擷取內容的編碼格式 * * @param charset 預設為 UTF-8 * @return */ public ZHttpRequest setCharset(String charset) { this.charset = charset; return this; } /** * 擷取 HTTP 要求響應資訊 * * @return */ public HttpResponse getHttpResponse() { return this.httpResponse; } /** * 擷取 HTTP 用戶端連線管理員 * * @return */ public HttpClient getHttpClient() { return this.httpClient; } /** * 擷取請求的狀態代碼 * * @return */ public int getStatusCode() { return this.statusCode; } /** * 通過 GET 方式請求資料 * * @param url * @return * @throws IOException */ public String get(String url) throws IOException { // 設定當前請求的連結 this.setUrl(url); // 執行個體化 GET 串連 this.httpGet = new HttpGet(this.url); // 自訂配置 header 資訊 this.addHeaders(this.httpGet); // 初始化用戶端請求 this.initHttpClient(); // 發送 HTTP 要求 this.httpResponse = this.httpClient.execute(this.httpGet); // 讀取遠端資料 this.getInputStream(); // 遠程請求狀態代碼是否正常 if (this.statusCode != HttpStatus.SC_OK) { return null; } // 返回全部讀取到的字串 return this.inputContent; } public String post(String url, Map datas, Map files) throws IOException { this.setUrl(url); // 執行個體化 GET 串連 this.httpPost = new HttpPost(this.url); // 自訂配置 header 資訊 this.addHeaders(this.httpPost); // 初始化用戶端請求 this.initHttpClient(); Iterator iterator = datas.entrySet().iterator(); MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); multipartEntityBuilder.setCharset(Charset.forName(this.charset)); // 發送的資料 while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); multipartEntityBuilder.addTextBody(entry.getKey(), entry.getValue(), ContentType.create(text/plain, Charset.forName(this.charset))); } // 發送的檔案 if (files != null) { iterator = files.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); String path = entry.getValue(); if (.equals(path) || path == null) continue; File file = new File(entry.getValue()); multipartEntityBuilder.addBinaryBody(entry.getKey(), file); } } // 產生 HTTP 實體 HttpEntity httpEntity = multipartEntityBuilder.build(); // 設定 POST 請求的實體部分 this.httpPost.setEntity(httpEntity); // 發送 HTTP 要求 this.httpResponse = this.httpClient.execute(this.httpPost); // 讀取遠端資料 this.getInputStream(); // 遠程請求狀態代碼是否正常 if (this.statusCode != HttpStatus.SC_OK) { return null; } // 返回全部讀取到的字串 return this.inputContent.toString(); } /** * 為 HTTP 要求添加 header 資訊 * * @param request */ protected void addHeaders(HttpRequestBase request) { if (this.headers != null) { Set keys = this.headers.entrySet(); Iterator iterator = keys.iterator(); Map.Entry entry; while (iterator.hasNext()) { entry = (Map.Entry) iterator.next(); request.addHeader(entry.getKey().toString(), entry.getValue().toString()); } } } /** * 配置請求參數 */ protected void setParams() { this.httpParameters = new BasicHttpParams(); this.httpParameters.setParameter(charset, this.charset); // 設定 串連請求逾時時間 HttpConnectionParams.setConnectionTimeout(this.httpParameters, this.connectionTimeout); // 設定 socket 讀取逾時時間 HttpConnectionParams.setSoTimeout(this.httpParameters, this.soTimeout); } /** * 初始化配置用戶端請求 */ protected void initHttpClient() { // 配置 HTTP 要求參數 this.setParams(); // 開啟一個用戶端 HTTP 要求 this.httpClient = new DefaultHttpClient(this.httpParameters); } /** * 讀取遠端資料 * * @throws IOException */ protected void getInputStream() throws IOException { // 接收遠程輸入資料流 InputStream inStream = this.httpResponse.getEntity().getContent(); // 分段讀取輸入資料流資料 ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int len = -1; while ((len = inStream.read(buf)) != -1) { baos.write(buf, 0, len); } // 將資料轉換為字串儲存 this.inputContent = new String(baos.toByteArray()); // 資料接收完畢退出 inStream.close(); // 擷取請求返回的狀態代碼 this.statusCode = this.httpResponse.getStatusLine().getStatusCode(); } /** * 關閉連線管理員釋放資源 */ protected void shutdownHttpClient() { if (this.httpClient != null && this.httpClient.getConnectionManager() != null) { this.httpClient.getConnectionManager().shutdown(); } }}
MainActivity.java
這個我就唯寫事件部分了
public void doClick(View view) { ZHttpRequest request = new ZHttpRequest(); String url = ; TextView textView = (TextView) findViewById(R.id.showContent); String content = 空內容; try { if (view.getId() == R.id.doGet) { url = http://www.baidu.com; content = GET資料: + request.get(url); } else { url = http://192.168.1.6/test.php; HashMap datas = new HashMap(); datas.put(p1, abc); datas.put(p2, 中文); datas.put(p3, abc中文cba); datas.put(pic, this.picPath); HashMap files = new HashMap(); files.put(file, this.picPath); content = POST資料: + request.post(url, datas, files); } } catch (IOException e) { content = IO異常: + e.getMessage(); } catch (Exception e) { content = 異常: + e.getMessage(); } textView.setText(content); }
其中的 this.picPath 就是指定的SD卡中的相片路徑 String 類型
activity_main.xml
由於我現在對Java 還不是很熟悉,只看過一些視頻教程,實際開發經驗不多,我按自己的理解寫的注釋,不過應該不會有什麼太大問題吧,如有錯誤請指出,謝謝!