一、GET 方法
使用 HttpClient 需要以下 6 個步驟:
1. 創建 HttpClient 的實例
2. 創建某種連接方法的實例,在這里是 GetMethod。在 GetMethod 的構造函數中傳入待連接的地址
3. 調用第一步中創建好的實例的 execute 方法來執行第二步中創建好的 method 實例
4. 讀 response
5. 釋放連接。無論執行方法是否成功,都必須釋放連接
6. 對得到后的內容進行處理
根據以上步驟,我們來編寫用GET方法取得某網頁內容的代碼。
1、大部分情況下 HttpClient 默認的構造函數已經足夠使用。
HttpClient httpClient = new HttpClient();
2、創建GET方法的實例。
在GET方法的構造函數中傳入待連接的地址即可。用GetMethod將會自動處理轉發過程,如果想要把自動處理轉發過程去掉的話,可以調用方法setFollowRedirects(false)。
GetMethod getMethod = new GetMethod( " http://www.ibm.com/ " );
3、調用 httpClient 的 executeMethod 方法來執行 getMethod。
由於是執行在網絡上的程序,在運行executeMethod方法的時候,需要處理兩個異常,分別是HttpException和 IOException。
HttpException:引起第一種異常的原因主要可能是在構造getMethod的時候傳入的協議不對,比如將"http"寫成了"htp",或者服務 器端返回的內容不正常等,並且該異常發生是不可恢復的;
IOException:一般是由於網絡原因引起的異常,對於這種異常 (IOException),HttpClient會根據你指定的恢復策略自動試着重新執行executeMethod方法。HttpClient的恢復 策略可以自定義(通過實現接口HttpMethodRetryHandler來實現)。通過httpClient的方法setParameter設置你實 現的恢復策略。
本例中使用的是系統提供的默認恢復策略,該策略在碰到第二類異常的時候將自動重試3次。executeMethod返回值是一個整數,表示 了執行該方法后服務器返回的狀態碼,該狀態碼能表示出該方法執行是否成功、需要認證或 者頁面發生了跳轉(默認狀態下GetMethod的實例是自動處理跳 轉的)等。
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler()); // 設置成了默認的恢復策略,在發生異常時候將自動重試3次,在這里你也可以設置成自定義的恢復策略
int statusCode = client.executeMethod(getMethod); // 執行getMethod if (statusCode != HttpStatus.SC_OK) { System.err.println( " Method failed: " + getMethod.getStatusLine()); }
4、在返回的狀態碼正確后,即可取得內容。
取得目標地址的內容有三種方法:
Ⅰ、getResponseBody,該方法返回的是目標的二進制的byte流;
Ⅱ、getResponseBodyAsString,這個方法返回的是String類型,值得注意的是該方法返回的String的編碼是根據系統默認的編碼方式,所以返回的String值可能編碼類型有誤;
Ⅲ、getResponseBodyAsStream,這個方法對於目標地址中有大量數據需要傳輸是最佳的。
在這里我們使用了最簡單的 getResponseBody方法。
byte [] responseBody = method.getResponseBody();
5、釋放連接。
無論執行方法是否成功,都必須釋放連接。
method.releaseConnection();
6、處理內容。
在這一步中根據你的需要處理內容,本例中只是簡單的將內容打印到控制台。System.out.println( new String(responseBody));
package com.asiainfo.hsop.common.utils; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.alibaba.fastjson.JSONObject; import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * 處理http和https協議請求,根據請求url判斷協議類型 * * @author yangxiaobing * @date 2017/9/6 */ public class HttpUtil { private static Logger logger = LogManager.getLogger(HttpUtil.class); private static final int HTTP_DEFAULT_TIMEOUT = 15000; //超時時間默認為15秒 private static final int HTTP_SOCKET_TIMEOUT = 30000; //連接狀態下沒有收到數據的話強制斷時間為30秒 private static final int MAX_TOTAL_CONNECTIONS = 500; //最大連接數 private static final int CONN_MANAGER_TIMEOUT = 500; //該值就是連接不夠用的時候等待超時時間,一定要設置,而且不能太大 private static MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager(); //接口調用頻繁,結果出現了很多ConnectTimeoutException 配置優化,共用HttpClient,減少開銷 static { //每主機最大連接數和總共最大連接數,通過hosfConfiguration設置host來區分每個主機 //client.getHttpConnectionManager().getParams().setDefaultMaxConnectionsPerHost(8); httpConnectionManager.getParams().setMaxTotalConnections(MAX_TOTAL_CONNECTIONS); httpConnectionManager.getParams().setConnectionTimeout(HTTP_DEFAULT_TIMEOUT);//連接超時時間 httpConnectionManager.getParams().setSoTimeout(HTTP_SOCKET_TIMEOUT); //連接狀態下沒有收到數據的話強制斷時間 httpConnectionManager.getParams().setLongParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, CONN_MANAGER_TIMEOUT); //是否計算節省帶寬 httpConnectionManager.getParams().setTcpNoDelay(true); //延遲關閉時間 httpConnectionManager.getParams().setLinger(0); //失敗的情況下會默認進行3次嘗試,成功之后不會再嘗試 ------關閉 httpConnectionManager.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0, false)); } /** * 構建 httpsclient 請求 * * @return */ private static HttpClient getHttpClient() { HttpClient httpClient = new HttpClient(httpConnectionManager); httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8"); return httpClient; } /** * POST請求統一入口 */ public static String post(String url, Map<String, Object> paramMap) { logger.info("===>>>調用[post]接口開始...===>>> URL:" + url); Long beginTime = System.currentTimeMillis(); if (StringUtils.isEmpty(url)) { return null; } String result = null; if (startsWithIgnoreCase(url, "https")) { result = httpsPost(url, paramMap, "UTF-8"); } else if (startsWithIgnoreCase(url, "http")) { result = httpPost(url, paramMap, "UTF-8"); } else { logger.warn("http url format error!"); } logger.info("===>>>調用[post]接口結束 ===>>>URL:" + url + ",耗時:" + (System.currentTimeMillis() - beginTime) + "毫秒"); return result; } /** * GET請求統一入口 */ public static String get(String url) { logger.info("===>>>調用[get]接口開始...===>>> URL:" + url); Long beginTime = System.currentTimeMillis(); if (StringUtils.isEmpty(url)) { return null; } String result = null; if (startsWithIgnoreCase(url, "https")) { result = httpsGet(url, "UTF-8"); } else if (startsWithIgnoreCase(url, "http")) { result = httpGet(url, "UTF-8"); } else { logger.warn("http url format error!"); } logger.info("===>>>調用[get]接口結束 ===>>>URL:" + url + ",耗時:" + (System.currentTimeMillis() - beginTime) + "毫秒"); return result; } public static String httpPost(String url, Map<String, Object> paramMap, String encoding) { String content = null; if (paramMap == null) { paramMap = new HashMap<String, Object>(); } logger.info("http param:" + paramMap.toString()); HttpClient httpClient = getHttpClient(); PostMethod method = new PostMethod(url); if (!paramMap.isEmpty()) { for (Map.Entry<String, ?> entry : paramMap.entrySet()) { method.addParameter(new NameValuePair(entry.getKey(), entry.getValue().toString())); } } try { httpClient.executeMethod(method); logger.info("http status : " + method.getStatusLine().getStatusCode()); content = new String(method.getResponseBody(), encoding); logger.info("http response : [" + content + "]"); } catch (Exception e) { logger.error("發起http請求失敗[" + url + "]" + ",param" + paramMap.toString(), e); } finally { method.releaseConnection(); httpClient.getHttpConnectionManager().closeIdleConnections(0); } return content; } public static String httpPost(String url, JSONObject param) { String content = null; CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(url); httpPost.setHeader("Content-Type", "application/json;charset=UTF-8"); StringEntity se = null; try { se = new StringEntity(JSONObject.toJSONString(param)); se.setContentType("text/json"); httpPost.setEntity(se); CloseableHttpResponse response = null; response = httpClient.execute(httpPost); HttpEntity httpEntity = response.getEntity(); content = EntityUtils.toString(httpEntity, "UTF-8"); } catch (IOException e) { e.printStackTrace(); } finally { if (httpClient != null) { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } return content; } private static String httpsPost(String url, Map<String, Object> paramMap, String encoding) { String content = null; HttpClient httpsClient = getHttpClient(); Protocol myhttps = new Protocol("https", new MySSLProtocolSocketFactory(), 443); Protocol.registerProtocol("https", myhttps); PostMethod method = new PostMethod(url); if (paramMap != null && !paramMap.isEmpty()) { for (Map.Entry<String, Object> entry : paramMap.entrySet()) { if (null != entry.getValue()) { method.addParameter(new NameValuePair(entry.getKey(), entry.getValue().toString())); } } logger.info("https param : " + paramMap.toString()); } try { httpsClient.executeMethod(method); logger.info("https status :" + method.getStatusLine().getStatusCode()); if (method.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { content = new String(method.getResponseBody(), encoding); logger.info("https response : [" + content + "]"); } } catch (Exception e) { logger.error("https request failed. url : [" + url + "]" + ", param : [" + paramMap + "]", e); } finally { method.releaseConnection(); httpsClient.getHttpConnectionManager().closeIdleConnections(0); } return content; } private static String httpGet(String url, String encoding) { HttpClient httpClient = getHttpClient(); GetMethod method = new GetMethod(url); String result = null; try { httpClient.executeMethod(method); int status = method.getStatusCode(); if (status == HttpStatus.SC_OK) { result = method.getResponseBodyAsString(); } else { logger.error("Method failed: " + method.getStatusLine()); } } catch (HttpException e) { // 發生致命的異常,可能是協議不對或者返回的內容有問題 logger.error("Please check your provided http address!"); logger.error(e, e); } catch (IOException e) { // 發生網絡異常 logger.error("發生網絡異常!"); logger.error(e, e); } finally { // 釋放連接 method.releaseConnection(); httpClient.getHttpConnectionManager().closeIdleConnections(0); } return result; } private static String httpsGet(String url, String encoding) { HttpClient httpsClient = getHttpClient();//HttpConnectionManager.alwaysClose=true Protocol myhttps = new Protocol("https", new MySSLProtocolSocketFactory(), 443); Protocol.registerProtocol("https", myhttps); GetMethod method = new GetMethod(url); String content = null; try { httpsClient.executeMethod(method); logger.info("https status : " + method.getStatusLine().getStatusCode()); if (method.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { content = new String(method.getResponseBody(), encoding); logger.info("https response : [" + content + "]"); } } catch (Exception e) { logger.error("https request failed. url : [" + url + "]", e.getCause()); } finally { method.releaseConnection(); httpsClient.getHttpConnectionManager().closeIdleConnections(0); } return content; } private static boolean startsWithIgnoreCase(String origin, String prefix) { int len = prefix.length(); if (len == 0 || origin.length() < len) { return false; } while (len-- > 0) { char a = origin.charAt(len); char b = prefix.charAt(len); if (a == b || Character.toUpperCase(a) == Character.toUpperCase(b)) { continue; } return false; } return true; } public static void main(String args[]) { // String url = "http://10.253.6.202:30001/dipic/api/auditControl/queryTraffic"; String url = "http://localhost:8180/comm/api/upload.do"; JSONObject Json = new JSONObject(); File file = new File("E:\\initParam.properties"); Map<String,String> map = new HashMap<>(); map.put("fileName","redis-64bit.rar"); System.out.println(HttpUtil.postFile(url, file)); } //文件上傳,調用fastDFS方法封裝層 public static String postFile(String url, File file){ CloseableHttpClient httpclient = HttpClients.createDefault(); CloseableHttpResponse response = null; String result = null; try { RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(3000) .setConnectTimeout(3000).setConnectionRequestTimeout(3000).build(); // if (params != null && !params.isEmpty()) { // List<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>(params.size()); // for (Map.Entry<String, String> entry : params.entrySet()) { // String value = entry.getValue(); // if (value != null) { // pairs.add(new BasicNameValuePair(entry.getKey(), value)); // } // } // url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset)); // } HttpPost httpPost = new HttpPost(url); httpPost.setConfig(requestConfig); // 將java.io.File對象添加到HttpEntity(org.apache.http.HttpEntity)對象中 MultipartEntityBuilder builder = MultipartEntityBuilder.create(); // 解決上傳文件,文件名中文亂碼問題 builder.setCharset(Charset.forName("utf-8")); builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);// 設置瀏覽器兼容模式 builder.addPart("file", new FileBody(file)); httpPost.setEntity(builder.build()); response = httpclient.execute(httpPost); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { HttpEntity resEntity = response.getEntity(); result = EntityUtils.toString(resEntity); // 消耗掉response EntityUtils.consume(resEntity); } } catch (Exception e) { e.printStackTrace(); }finally { if(response!=null){ try { response.close(); } catch (IOException e) { e.printStackTrace(); } } if(httpclient!=null){ try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } }
package test; import java.io.IOException; import org.apache.commons.httpclient. * ; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.params.HttpMethodParams; public class GetSample{ public static void main(String[] args) { // 構造HttpClient的實例 HttpClient httpClient = new HttpClient(); // 創建GET方法的實例 GetMethod getMethod = new GetMethod( " http://www.ibm.com " ); // 使用系統提供的默認的恢復策略 getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); try { // 執行getMethod int statusCode = httpClient.executeMethod(getMethod); if (statusCode != HttpStatus.SC_OK) { System.err.println( " Method failed: " + getMethod.getStatusLine()); } // 讀取內容 byte [] responseBody = getMethod.getResponseBody(); // 處理內容 System.out.println( new String(responseBody)); } catch (HttpException e) { // 發生致命的異常,可能是協議不對或者返回的內容有問題 System.out.println( " Please check your provided http address! " ); e.printStackTrace(); } catch (IOException e) { // 發生網絡異常 e.printStackTrace(); } finally { // 釋放連接 getMethod.releaseConnection(); } } }
