httpclient4.5如何以二進位制流的形式上傳檔案
阿新 • • 發佈:2019-01-09
本人在做介面測試的過程中,遇到了上傳檔案的測試。由於之前沒有測試過流上傳,導致花費了一些時間,還有就是網上關於httpclient4.5的資料和其他版本資料混在一起,也浪費了一些時間。經過測試終於可用了。暫時沒有進一步封裝,下面分享一些主要的程式碼。其實 httpclient 物件我在一個基礎類中以靜態變數的形式一開始就載入好了,為了減少理解的障礙,我後面會把建立httpclient 的方法也附帶在後面。
其中output 方法在另外一篇文章中寫過了,這裡就不多寫了,只是一個格式化輸出 json 物件的方法。public void uploadPic() throws FileNotFoundException { HttpPost httppost = new HttpPost(url); // 建立二進位制檔案流 InputStream inputStream = new FileInputStream(file); StringBody index = new StringBody("7", ContentType.create("text/plain", Consts.UTF_8)); // 建立 part contentBody,第一個是值,第二個引數是型別,第三個引數是編碼格式 // 建立MultipartEntityBuilder物件 MultipartEntityBuilder builder = MultipartEntityBuilder.create(); // 新增二進位制檔案流,第一個引數是介面引數名,第二個引數是檔案的二進位制流,第三個引數是檔名 builder.addBinaryBody("user_pic", inputStream, ContentType.create("multipart/form-data"), "11.png"); // 新增引數和引數值 builder.addPart("user_pic_index", index); // 建立 httpentity 實體 HttpEntity httpEntity = builder.build(); // 設定 httpentity 實體 httppost.setEntity(httpEntity); // 傳送請求獲取相應 JSONObject response = getHttpResponseEntityByJson(httppost); output(response); }
下面是getHttpResponseEntityByJson方法:
/** * 獲取響應實體,暫無header設定 * * @param request * 請求物件 * @return 返回json型別的物件 */ public JSONObject getHttpResponseEntityByJson(HttpRequestBase request) { output(request.getURI()); JSONObject jsonObject = new JSONObject(); CloseableHttpResponse response = null;// 建立響應物件 long data_size = 0;// 用於存放資料大小 Map<String, String> info = getRequestInfo(request); String api_name = info.get("api_name"); String type = info.get("type"); String host_name = info.get("host_name"); String method = info.get("method"); String uri = info.get("uri"); String params = info.get("params"); request.addHeader(HTTP.USER_AGENT, "okhttp/3.9.1");// 符合應用防火牆 mark = getMark(); Date start = getDate();// 記錄開始時間 try { response = httpClient.execute(request); } catch (ClientProtocolException e1) { output("client請求異常", e1); } catch (IOException e1) { output("執行請求時java IO 異常!", e1); } // 獲取響應 Date end = getDate();// 記錄結束時間 double elapsed_time = outputTimeDiffer(start, end);// 獲取響應耗時 int status = response.getStatusLine().getStatusCode();// 獲取響應狀態 HttpEntity entity = response.getEntity();// 獲取響應實體 data_size = entity.getContentLength();// 獲取相應資料大小 if (data_size == -1) {// 如果為-1,則重置data_size data_size = 0; } String content = null; try { content = EntityUtils.toString(entity, "utf-8");// 用string接收響應實體 EntityUtils.consume(entity);// 消耗響應實體 } catch (ParseException e1) { output("解析響應實體異常!", e1); } catch (IOException e1) { output("解析響應實體時java IO 異常!", e1); } // 解析響應 try { response.close(); } catch (IOException e2) { output("響應關閉失敗!", e2); } if (data_size == 0) {// 如果被重置或者沒有獲取到,則data_size等於解析string大小 try { data_size = content.length(); } catch (Exception e) { data_size = 1; output("獲取響應長度異常!", e); } } if (status == 200) { try { jsonObject = JSONObject.fromObject(content); } catch (Exception e) { output("相應狀態碼錯誤,相應內容:" + content, e); } } else { output("響應內容:" + content); } // request.releaseConnection();//此處容易造成socket close,在連線池時使用 MySqlTest.getInstance().saveApiTestDate(host_name, api_name, data_size, elapsed_time, status, type, mark, method, uri, params); return jsonObject; }
中間涉及到獲取資訊getRequestInfo方法如下:
下面是載入 httpclient 物件的方法:/** * 封裝獲取請求的各種資訊的方法 * * @param httpRequestBase * 傳入請求物件 * @return 返回一個map,包含api_name,host_name,type,method,params */ public Map<String, String> getRequestInfo(HttpRequestBase request) { Map<String, String> info = new HashMap<>();// 新建map儲存資訊 String method = request.getMethod();// 獲取method info.put("method", method); String uri = request.getURI().toString();// 獲取uri info.put("uri", uri); String url = uri; if (uri.contains("?")) {// 獲取url,如果是get請求,先擷取 url = uri.substring(0, uri.indexOf("?")); } String one = url.substring(url.indexOf("//") + 2);// 刪除掉http:// String api_name = one.substring(one.indexOf("/"));// 獲取介面名 info.put("api_name", api_name); String host_name = one.substring(0, one.indexOf("/"));// 獲取host地址 info.put("host_name", host_name); String type = url.substring(0, url.indexOf("//") - 1);// 獲取協議型別 info.put("type", type); String params = null;// 引數 if (method.equals("GET")) { params = uri.substring(uri.indexOf("?") + 1, uri.length()); } else if (method.equals("POST")) { HttpPost httpPost = (HttpPost) request;// 強轉httppost請求 HttpEntity entity = httpPost.getEntity();// 獲取實體 try { params = EntityUtils.toString(entity);// 解析實體 EntityUtils.consume(entity);// 確保實體消耗 } catch (ParseException e) { output("解析響應實體異常!", e); } catch (IOException e) { output("解析響應實體時java IO 異常!", e); } catch (UnsupportedOperationException e) { params = "entity型別:" + entity.getClass(); output("不被支援的entity 型別!", e); } } info.put("params", params); return info; }
public static CloseableHttpClient httpClient = getCloseableHttpClients();
/**
* 獲取httpclient物件
*
* @return 返回HTTPclient物件
*/
public static CloseableHttpClient getCloseableHttpClients() {
return HttpClients.createDefault();
}
末了再次宣傳一下自己的 QQ群:群號:340964272。