使用HttpClient發(fā)送請求翘盖、接收響應(yīng)很簡單桂塞,一般需要如下幾步即可:
- 創(chuàng)建CloseableHttpClient對象。
- 創(chuàng)建請求方法的實(shí)例馍驯,并指定請求URL阁危。如果需要發(fā)送GET請求,創(chuàng)建HttpGet對象汰瘫;如果需要發(fā)送POST請求狂打,創(chuàng)建HttpPost對象。
- 如果需要發(fā)送請求參數(shù)混弥,可可調(diào)用setEntity(HttpEntity entity)方法來設(shè)置請求參數(shù)趴乡。setParams方法已過時(4.4.1版本)。
- 調(diào)用HttpGet蝗拿、HttpPost對象的setHeader(String name, String value)方法設(shè)置header信息晾捏,或者調(diào)用setHeaders(Header[] headers)設(shè)置一組header信息。
- 調(diào)用CloseableHttpClient對象的execute(HttpUriRequest request)發(fā)送請求哀托,該方法返回一個CloseableHttpResponse惦辛。
- 調(diào)用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務(wù)器的響應(yīng)內(nèi)容仓手。程序可通過該對象獲取服務(wù)器的響應(yīng)內(nèi)容胖齐;調(diào)用CloseableHttpResponse的getAllHeaders()玻淑、getHeaders(String name)等方法可獲取服務(wù)器的響應(yīng)頭。
- 釋放連接呀伙。無論執(zhí)行方法是否成功补履,都必須釋放連接
首先使用maven添加依賴:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
具體代碼如下:
/**
* @Author: grootdu
* @Description:
* @Date: Created in 11:56 2018/11/17
* @Modified By:
*/
public class HttpClientUtil {
private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
public static String doGet(String url, Map<String, String> params, Map<String, String> headers, RequestConfig config) throws Exception{
String res = "";
// 創(chuàng)建Httpclient對象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
// 創(chuàng)建uri
URIBuilder builder = new URIBuilder(url);
if (params != null) {
for (String key : params.keySet()) {
builder.addParameter(key, params.get(key));
}
}
URI uri = builder.build();
// 創(chuàng)建http GET請求
HttpGet httpGet = new HttpGet(uri);
// HttpGet httpGet = new HttpGet(url);//如果url后面帶了全部參數(shù)的話 也可以直接用這種方式直接創(chuàng)建get請求
if (headers != null) {
for (String key : headers.keySet()) {
httpGet.addHeader(key, headers.get(key));
}
}
try {
if(config!=null){
// 構(gòu)建請求配置信息
// RequestConfig config = RequestConfig.custom().setConnectTimeout(1000) // 創(chuàng)建連接的最長時間
// .setConnectionRequestTimeout(500) // 從連接池中獲取到連接的最長時間
// .setSocketTimeout(10 * 1000) // 數(shù)據(jù)傳輸?shù)淖铋L時間
// .setStaleConnectionCheckEnabled(true) // 提交請求前測試連接是否可用
// .build();
httpGet.setConfig(config);
}
// 執(zhí)行請求操作,并拿到結(jié)果(同步阻塞)
response = httpClient.execute(httpGet);
//獲取結(jié)果實(shí)體
HttpEntity entity = response.getEntity();
// 判斷返回狀態(tài)是否為200
if (response.getStatusLine().getStatusCode() == 200 && entity != null) {
//按指定編碼(這里為UTF8編碼)轉(zhuǎn)換結(jié)果實(shí)體為String類型
res = EntityUtils.toString(entity, "UTF-8");
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw e;
} finally {
httpGet.releaseConnection();
try {
httpClient.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
return res;
}
public static String doPost(String url, RequestConfig config) throws Exception {
return doPost(url, null,config);
}
public static String doPost(String url, Map<String, String> params, RequestConfig config, Map<String, String> headParams) throws Exception {
//對于params中key value剿另,如果是其他類型干像,比如數(shù)組的話,用下面的doPostJson方法更適合驰弄,即直接將入?yún)⑵闯蒵son字符串,JSONObject.toJSONString(map)
String res = "";
// 創(chuàng)建Httpclient對象
CloseableHttpClient httpClient = HttpClients.createDefault();
// 創(chuàng)建Http Post請求對象
HttpPost httpPost = new HttpPost(url);
if(headParams != null){
for(String key : headParams.keySet()){
httpPost.addHeader(key, headParams.get(key));
}
}
try {
if(config!=null){
httpPost.setConfig(config);
}
// 創(chuàng)建參數(shù)列表
if (params != null) {
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
for (String key : params.keySet()) {
paramList.add(new BasicNameValuePair(key, params.get(key)));
}
// 創(chuàng)建請求內(nèi)容
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
// 設(shè)置參數(shù)到請求對象中
httpPost.setEntity(entity);
}
// 執(zhí)行http請求
CloseableHttpResponse response = httpClient.execute(httpPost);
res = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw e;
} finally {
httpPost.releaseConnection();
try {
httpClient.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
return res;
}
public static String doPostJson(String url, String json, RequestConfig config) throws Exception {
String res = "";
// 創(chuàng)建Httpclient對象
CloseableHttpClient httpClient = HttpClients.createDefault();
// 創(chuàng)建Http Post請求
HttpPost httpPost = new HttpPost(url);
try {
if (config != null) {
httpPost.setConfig(config);
}
// 設(shè)置參數(shù)到請求對象中
httpPost.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
// 執(zhí)行http請求
CloseableHttpResponse response = httpClient.execute(httpPost);
// 獲取結(jié)果實(shí)體
HttpEntity entity = response.getEntity();
if(entity != null){
res = EntityUtils.toString(entity, "utf-8");
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw e;
} finally {
httpPost.releaseConnection();
try {
httpClient.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
return res;
}
public static byte[] doPost(String url, byte[] data) throws Exception {
byte[] res = null;
HttpPost httpPost = new HttpPost(url);
//CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpClient httpClient = HttpClients.custom().disableAutomaticRetries().build(); // disable retry
try {
// init post
/*if (params != null && !params.isEmpty()) {
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : params.entrySet()) {
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
}*/
// timeout
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(10000)
.setSocketTimeout(10000)
.setConnectTimeout(10000)
.build();
httpPost.setConfig(requestConfig);
// data
if (data != null) {
httpPost.setEntity(new ByteArrayEntity(data, ContentType.DEFAULT_BINARY));
}
// do post
HttpResponse response = httpClient.execute(httpPost);
// 獲取結(jié)果實(shí)體
HttpEntity entity = response.getEntity();
if (null != entity) {
res = EntityUtils.toByteArray(entity);
EntityUtils.consume(entity);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw e;
} finally {
httpPost.releaseConnection();
try {
httpClient.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
return res;
}
/**
* read bytes from http request
* @param request
* @return
* @throws IOException
*/
public static final byte[] readBytes(HttpServletRequest request) throws IOException {
request.setCharacterEncoding("UTF-8");
int contentLen = request.getContentLength();
InputStream is = request.getInputStream();
if (contentLen > 0) {
int readLen = 0;
int readLengthThisTime = 0;
byte[] message = new byte[contentLen];
try {
while (readLen != contentLen) {
readLengthThisTime = is.read(message, readLen, contentLen - readLen);
if (readLengthThisTime == -1) {
break;
}
readLen += readLengthThisTime;
}
return message;
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw e;
}
}
return new byte[] {};
}
}
對于HTTPS的訪問速客,采取繞過證書的策略:
/**
* @Author: grootdu
* @Description:
* @Date: Created in 16:12 2018/11/14
* @Modified By:
*/
public class HttpsClientUtil {
private static Logger logger = LoggerFactory.getLogger(HttpsClientUtil.class);
/**
* 繞過驗(yàn)證
*
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSLv3");
// 實(shí)現(xiàn)一個X509TrustManager接口戚篙,用于繞過驗(yàn)證,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sc.init(null, new TrustManager[] { trustManager }, null);
return sc;
}
/**
* 模擬請求
*
* @param url
* @param param
* @param
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws IOException
* @throws ClientProtocolException
*/
public static String doGet(String url, Map<String,String> param, RequestConfig config) throws Exception {
String res = "";
//采用繞過驗(yàn)證的方式處理https請求
SSLContext sslcontext = createIgnoreVerifySSL();
// 設(shè)置協(xié)議http和https對應(yīng)的處理socket鏈接工廠的對象
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslcontext))
.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
//創(chuàng)建自定義的httpclient對象
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connManager).build();
// 創(chuàng)建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 創(chuàng)建http GET請求
HttpGet httpGet = new HttpGet(uri);
try {
if(config!=null){
httpGet.setConfig(config);
}
// 執(zhí)行請求
CloseableHttpResponse response = httpClient.execute(httpGet);
// 判斷返回狀態(tài)是否為200
if (response.getStatusLine().getStatusCode() == 200) {
res = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw e;
} finally {
httpGet.releaseConnection();
try {
httpClient.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
return res;
}
}
參考博客:
https://www.cnblogs.com/Mr-Rocker/p/6229652.html
https://www.cnblogs.com/moy25/p/8658762.html
https://www.656463.com/article/httpclientqingqiucanshushezhi_8