跨域請求httpclient
阿新 • • 發佈:2017-08-05
t對象 pair etl actor sock slf4j .cn factor odi
httpclient:是Apache工具包,util,它可以作為一個爬蟲,直接爬取某個互聯網上的頁面。獲取到時頁面最終的源文件html。直接可以獲取頁面返回json。就可以直接在代碼內部模擬發起http請求。請求的結果也被捕捉。在代碼內部將獲取的json,利用JacksonObjectMapper對象,把json字符串轉成java對象。
與Spring框架整合:
1、引入jar支持
<!-- httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.5</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.3.1</version> </dependency>
2、applicationContext-httpclient.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 定義httpclient連接池 --> <bean id="httpClientConnectionManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager" destroy-method="close"> <!-- 設置連接總數 --> <property name="maxTotal" value="${http.pool.maxTotal}"></property> <!-- 設置每個地址的並發數 --> <property name="defaultMaxPerRoute" value="${http.pool.defaultMaxPerRoute}"></property> </bean> <!-- 定義 HttpClient工廠,這裏使用HttpClientBuilder構建--> <bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create"> <property name="connectionManager" ref="httpClientConnectionManager"></property> </bean> <!-- 得到httpClient的實例 --> <bean id="httpClient" factory-bean="httpClientBuilder" factory-method="build"/> <!-- 定期清理無效的連接 --> <bean class="com.jt.common.util.IdleConnectionEvictor" destroy-method="shutdown"> <constructor-arg index="0" ref="httpClientConnectionManager" /> <!-- 間隔一分鐘清理一次 --> <constructor-arg index="1" value="600000" /> </bean> <!-- 定義requestConfig的工廠 --> <bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig.Builder"> <!-- 從連接池中獲取到連接的最長時間 --> <property name="connectionRequestTimeout" value="${http.request.connectionRequestTimeout}"/> <!-- 創建連接的最長時間 --> <property name="connectTimeout" value="${http.request.connectTimeout}"/> <!-- 數據傳輸的最長時間 --> <property name="socketTimeout" value="${http.request.socketTimeout}"/> <!-- 提交請求前測試連接是否可用 --> <property name="staleConnectionCheckEnabled" value="${http.request.staleConnectionCheckEnabled}"/> </bean> <!-- 得到requestConfig實例 --> <bean id="requestConfig" factory-bean="requestConfigBuilder" factory-method="build" /> </beans>
3、把httpClient對象封裝成偽service。在程序中註入,封裝doGet,doPost,doJson- ---- HttpClientService:
package com.jt.common.service; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.http.NameValuePair; 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.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class HttpClientService { private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientService.class); @Autowired(required=false) private CloseableHttpClient httpClient; @Autowired(required=false) private RequestConfig requestConfig; /** * 執行get請求 * * @param url * @return * @throws Exception */ public String doGet(String url,Map<String, String> params,String encode) throws Exception { LOGGER.info("執行GET請求,URL = {}", url); if(null != params){ URIBuilder builder = new URIBuilder(url); for (Map.Entry<String, String> entry : params.entrySet()) { builder.setParameter(entry.getKey(), entry.getValue()); } url = builder.build().toString(); } // 創建http GET請求 HttpGet httpGet = new HttpGet(url); httpGet.setConfig(requestConfig); CloseableHttpResponse response = null; try { // 執行請求 response = httpClient.execute(httpGet); // 判斷返回狀態是否為200 if (response.getStatusLine().getStatusCode() == 200) { if(encode == null){ encode = "UTF-8"; } return EntityUtils.toString(response.getEntity(), encode); } } finally { if (response != null) { response.close(); } // 此處不能關閉httpClient,如果關閉httpClient,連接池也會銷毀 } return null; } public String doGet(String url, String encode) throws Exception{ return this.doGet(url, null, encode); } public String doGet(String url) throws Exception{ return this.doGet(url, null, null); } /** * 帶參數的get請求 * * @param url * @param params * @return * @throws Exception */ public String doGet(String url, Map<String, String> params) throws Exception { return this.doGet(url, params, null); } /** * 執行POST請求 * * @param url * @param params * @return * @throws Exception */ public String doPost(String url, Map<String, String> params,String encode) throws Exception { // 創建http POST請求 HttpPost httpPost = new HttpPost(url); httpPost.setConfig(requestConfig); if (null != params) { // 設置2個post參數,一個是scope、一個是q List<NameValuePair> parameters = new ArrayList<NameValuePair>(0); for (Map.Entry<String, String> entry : params.entrySet()) { parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } // 構造一個form表單式的實體 UrlEncodedFormEntity formEntity = null; if(encode!=null){ formEntity = new UrlEncodedFormEntity(parameters,encode); }else{ formEntity = new UrlEncodedFormEntity(parameters); } // 將請求實體設置到httpPost對象中 httpPost.setEntity(formEntity); } CloseableHttpResponse response = null; try { // 執行請求 response = httpClient.execute(httpPost); // 判斷返回狀態是否為200 if (response.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(response.getEntity(), "UTF-8"); } } finally { if (response != null) { response.close(); } } return null; } /** * 執行POST請求 * * @param url * @param params * @return * @throws Exception */ public String doPost(String url, Map<String, String> params) throws Exception { // 創建http POST請求 HttpPost httpPost = new HttpPost(url); httpPost.setConfig(requestConfig); if (null != params) { // 設置2個post參數,一個是scope、一個是q List<NameValuePair> parameters = new ArrayList<NameValuePair>(0); for (Map.Entry<String, String> entry : params.entrySet()) { parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } // 構造一個form表單式的實體 UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters); // 將請求實體設置到httpPost對象中 httpPost.setEntity(formEntity); } CloseableHttpResponse response = null; try { // 執行請求 response = httpClient.execute(httpPost); // 判斷返回狀態是否為200 if (response.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(response.getEntity(), "UTF-8"); } } finally { if (response != null) { response.close(); } } return null; } public String doPostJson(String url, String json) throws Exception { // 創建http POST請求 HttpPost httpPost = new HttpPost(url); httpPost.setConfig(requestConfig); if(null != json){ //設置請求體為 字符串 StringEntity stringEntity = new StringEntity(json,"UTF-8"); httpPost.setEntity(stringEntity); } CloseableHttpResponse response = null; try { // 執行請求 response = httpClient.execute(httpPost); // 判斷返回狀態是否為200 if (response.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(response.getEntity(), "UTF-8"); } } finally { if (response != null) { response.close(); } } return null; } }
4、在程序中註入httpClientService,直接調用doGet。
5、在applicationContext.xml中加入<value>classpath:httpclient.properties</value>
httpclient.properties:
#從連接池中獲取到連接的最長時間 http.request.connectionRequestTimeout=500 #5000 http.request.connectTimeout=5000 #數據傳輸的最長時間 http.request.socketTimeout=30000 #提交請求前測試連接是否可用 http.request.staleConnectionCheckEnabled=true #設置連接總數 http.pool.maxTotal=200 #設置每個地址的並發數 http.pool.defaultMaxPerRoute=100
跨域請求httpclient