1. 程式人生 > >HttpClient遠端呼叫以及整合SpringBoot

HttpClient遠端呼叫以及整合SpringBoot

一、HttpClient

1.1、 前臺系統訪問後臺介面的方式

兩個系統間如何互相訪問?兩個tomcat上的專案如何互相訪問

採用HttpClient實現跨系統的介面呼叫。

1.2、 什麼是HttpClient

在這裡插入圖片描述

官網:http://hc.apache.org/index.html

現在也叫:HttpComponents 在這裡插入圖片描述

特點:

  1. HttpClient別名:HttoComponents

  2. HttpClient可以傳送get、post、put、delete、…等請求

在這裡插入圖片描述

在這裡插入圖片描述

1.3、 HttpClient入門案例

<
dependency
>
<groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.4</version> </dependency>

1.3.1、 發起Get請求

1建立一個客戶端 CloseableHttpClient

2建立一個get方法請求例項 HttpGet

3傳送請求 execute

4獲取響應的頭資訊

5獲取響應的主題內容

6關閉響應物件

使用HttpClient發起Get請求的案例程式碼:

public class DoGET {

    public static void main(String[] args) throws Exception {
        // 建立Httpclient物件,相當於打開了瀏覽器
        CloseableHttpClient httpclient = HttpClients.createDefault();

        // 建立HttpGet請求,相當於在瀏覽器輸入地址
        HttpGet httpGet = new HttpGet("http://www.baidu.com/"
); CloseableHttpResponse response = null; try { // 執行請求,相當於敲完地址後按下回車。獲取響應 response = httpclient.execute(httpGet); // 判斷返回狀態是否為200 if (response.getStatusLine().getStatusCode() == 200) { // 解析響應,獲取資料 String content = EntityUtils.toString(response.getEntity(), "UTF-8"); System.out.println(content); } } finally { if (response != null) { // 關閉資源 response.close(); } // 關閉瀏覽器 httpclient.close(); } } }

執行日誌:

請求頭:

在這裡插入圖片描述

響應頭:

在這裡插入圖片描述

資料:

在這裡插入圖片描述

1.3.2、 帶引數的Get請求

1建立一個客戶端 CloseableHttpClient

2 通過URIBuilder傳遞引數

3建立一個get方法請求例項 HttpGet

4傳送請求 execute

5獲取響應的頭資訊

6獲取響應的主題內容

7關閉響應物件

訪問網站的爬蟲協議:

在這裡插入圖片描述

public class DoGETParam {

   public static void main(String[] args) throws Exception {
       // 建立Httpclient物件
       CloseableHttpClient httpclient = HttpClients.createDefault();
       // 建立URI物件,並且設定請求引數
       URI uri = new URIBuilder("http://www.baidu.com/s").setParameter("wd", "java").build();
       // 建立http GET請求
       HttpGet httpGet = new HttpGet(uri);

       CloseableHttpResponse response = null;
       try {
           // 執行請求
           response = httpclient.execute(httpGet);
           // 判斷返回狀態是否為200
           if (response.getStatusLine().getStatusCode() == 200) {
               // 解析響應資料
               String content = EntityUtils.toString(response.getEntity(), "UTF-8");
               System.out.println(content);
           }
       } finally {
           if (response != null) {
               response.close();
           }
           httpclient.close();
       }
   }
}

1.3.3、 發起POST請求

/*
* 演示:使用HttpClient發起POST請求
*/
public class DoPOST {
   public static void main(String[] args) throws Exception {
       // 建立Httpclient物件
       CloseableHttpClient httpclient = HttpClients.createDefault();
       // 建立http POST請求
       HttpPost httpPost = new HttpPost("http://www.oschina.net/");
       // 把自己偽裝成瀏覽器。否則開源中國會攔截訪問
       httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");

       CloseableHttpResponse response = null;
       try {
           // 執行請求
           response = httpclient.execute(httpPost);
           // 判斷返回狀態是否為200
           if (response.getStatusLine().getStatusCode() == 200) {
               // 解析響應資料
               String content = EntityUtils.toString(response.getEntity(), "UTF-8");
               System.out.println(content);
           }
       } finally {
           if (response != null) {
               response.close();
           }
           // 關閉瀏覽器
           httpclient.close();
       }

   }
}

1.3.4、 帶引數POST請求

/*
* 演示:使用HttpClient發起帶有引數的POST請求
*/
public class DoPOSTParam {

   public static void main(String[] args) throws Exception {
       // 建立Httpclient物件
       CloseableHttpClient httpclient = HttpClients.createDefault();
       // 建立http POST請求,訪問開源中國
       HttpPost httpPost = new HttpPost("http://www.oschina.net/search");

       // 根據開源中國的請求需要,設定post請求引數
       List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);
       parameters.add(new BasicNameValuePair("scope", "project"));
       parameters.add(new BasicNameValuePair("q", "java"));
       parameters.add(new BasicNameValuePair("fromerr", "8bDnUWwC"));
       // 構造一個form表單式的實體
       UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
       // 將請求實體設定到httpPost物件中
       httpPost.setEntity(formEntity);

       CloseableHttpResponse response = null;
       try {
           // 執行請求
           response = httpclient.execute(httpPost);
           // 判斷返回狀態是否為200
           if (response.getStatusLine().getStatusCode() == 200) {
               // 解析響應體
               String content = EntityUtils.toString(response.getEntity(), "UTF-8");
               System.out.println(content);
           }
       } finally {
           if (response != null) {
               response.close();
           }
           // 關閉瀏覽器
           httpclient.close();
       }
   }
}

二、專案整合HttpClient—與SpringBoot整合

SpringBoot官方並沒有對HttpClient的啟動器。所以我們需要自己完成配置,還好,我們剛才在測試案例中已經寫過了。

不過,SpringBoot雖然沒有提供啟動器,但是卻提供了一個對Restful服務進行呼叫的模板類:RestTemplate,底層可以使用HttpClient來實現。有了這個我們就無需自己定義APIService了。

1、匯入maven座標

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

2、在bos_management中建立HttpClientConfig類

在這裡插入圖片描述

2、在application.properties新增如下配置:

#The config for HttpClient 
http.maxTotal=300
http.defaultMaxPerRoute=50
http.connectTimeout=1000
http.connectionRequestTimeout=500
http.socketTimeout=5000
http.staleConnectionCheckEnabled=true

3、在類中編寫程式碼

/**
 * HttpClient的配置類
 */
@Configuration
@ConfigurationProperties(prefix = "http", ignoreUnknownFields = true)
public class HttpClientConfig {

    private Integer maxTotal;// 最大連線

    private Integer defaultMaxPerRoute;// 每個host的最大連線

    private Integer connectTimeout;// 連線超時時間

    private Integer connectionRequestTimeout;// 請求超時時間

    private Integer socketTimeout;// 響應超時時間

    /**
     * HttpClient連線池
     * @return
     */
    @Bean
    public HttpClientConnectionManager httpClientConnectionManager() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(maxTotal);
        connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
        return connectionManager;
    }

    /**
     * 註冊RequestConfig
     * @return
     */
    @Bean
    public RequestConfig requestConfig() {
        return RequestConfig.custom().setConnectTimeout(connectTimeout)
            .setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout)
            .build();
    }

    /**
     * 註冊HttpClient
     * @param manager
     * @param config
     * @return
     */
    @Bean
    public HttpClient httpClient(HttpClientConnectionManager manager, RequestConfig config) {
        return HttpClientBuilder.create().setConnectionManager(manager).setDefaultRequestConfig(config)
            .build();
    }

    @Bean
    public ClientHttpRequestFactory requestFactory(HttpClient httpClient) {
        return new HttpComponentsClientHttpRequestFactory(httpClient);
    }
    /**
     * 使用HttpClient來初始化一個RestTemplate
     * @param requestFactory
     * @return
     */
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory requestFactory) {
        RestTemplate template = new RestTemplate(requestFactory);

        List<HttpMessageConverter<?>> list = template.getMessageConverters();
        for (HttpMessageConverter<?> mc : list) {
            if (mc instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) mc).setDefaultCharset(Charset.forName("UTF-8"));
            }
        }
        return template;
    }

    public Integer getMaxTotal() {
        return maxTotal;
    }

    public void setMaxTotal(Integer maxTotal) {
        this.maxTotal = maxTotal;
    }

    public Integer getDefaultMaxPerRoute() {
        return defaultMaxPerRoute;
    }

    public void setDefaultMaxPerRoute(Integer defaultMaxPerRoute) {
        this.defaultMaxPerRoute = defaultMaxPerRoute;
    }

    public Integer getConnectTimeout() {
        return connectTimeout;
    }

    public void setConnectTimeout(Integer connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    public Integer getConnectionRequestTimeout() {
        return connectionRequestTimeout;
    }

    public void setConnectionRequestTimeout(Integer connectionRequestTimeout) {
        this.connectionRequestTimeout = connectionRequestTimeout;
    }

    public Integer getSocketTimeout() {
        return socketTimeout;
    }

    public void setSocketTimeout(Integer socketTimeout) {
        this.socketTimeout = socketTimeout;
    }
}