大忙人系列_RabbitMQ通過java HttpClient代碼獲取服務器上的所有交換機、隊列

如圖所示,我們可以找到HttpClient的API地址,通過賬號密碼我們可以在瀏覽器中獲得相關的RabbitMQ的數據。

當我們獲得所有的API以後,我們可以通過HttpClient遠程調用API獲得RabbitMQ的隊列、交換機等信息。

但是我們是使用HttpClient會獲得如下異常:

錯誤一:報405異常

18:18:05.793 [main] DEBUG org.apache.http.client.protocol.RequestAddCookies - CookieSpec selected: default
18:18:05.819 [main] DEBUG org.apache.http.client.protocol.RequestAuthCache - Auth cache not set in the context
18:18:05.821 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection request: [route: {}->http://127.0.0.1:15672][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
18:18:05.855 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {}->http://127.0.0.1:15672][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
18:18:05.858 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Opening connection {}->http://127.0.0.1:15672
18:18:05.864 [main] DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connecting to /127.0.0.1:15672
18:18:05.867 [main] DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connection established 127.0.0.1:15649<->127.0.0.1:15672
18:18:05.867 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Executing request POST /api/exchanges HTTP/1.1
18:18:05.868 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Target auth state: UNCHALLENGED
18:18:05.869 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Proxy auth state: UNCHALLENGED
18:18:05.874 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> POST /api/exchanges HTTP/1.1
18:18:05.874 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Content-Length: 0
18:18:05.874 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Host: 127.0.0.1:15672
18:18:05.874 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Connection: Keep-Alive
18:18:05.874 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.1 (Java/1.8.0_101)
18:18:05.874 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
18:18:05.874 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "POST /api/exchanges HTTP/1.1[\r][\n]"
18:18:05.874 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Content-Length: 0[\r][\n]"
18:18:05.874 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Host: 127.0.0.1:15672[\r][\n]"
18:18:05.874 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
18:18:05.874 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.1 (Java/1.8.0_101)[\r][\n]"
18:18:05.874 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
18:18:05.874 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
18:18:05.926 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "HTTP/1.1 405 Method Not Allowed[\r][\n]"
18:18:05.927 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "allow: HEAD, GET, OPTIONS[\r][\n]"
18:18:05.927 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "content-length: 0[\r][\n]"
18:18:05.927 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "date: Thu, 06 Dec 2018 10:15:10 GMT[\r][\n]"
18:18:05.927 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "server: Cowboy[\r][\n]"
18:18:05.927 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "vary: origin[\r][\n]"
18:18:05.927 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
18:18:05.932 [main] DEBUG org.apache.http.headers - http-outgoing-0 << HTTP/1.1 405 Method Not Allowed
18:18:05.932 [main] DEBUG org.apache.http.headers - http-outgoing-0 << allow: HEAD, GET, OPTIONS
18:18:05.932 [main] DEBUG org.apache.http.headers - http-outgoing-0 << content-length: 0
18:18:05.932 [main] DEBUG org.apache.http.headers - http-outgoing-0 << date: Thu, 06 Dec 2018 10:15:10 GMT
18:18:05.932 [main] DEBUG org.apache.http.headers - http-outgoing-0 << server: Cowboy
18:18:05.932 [main] DEBUG org.apache.http.headers - http-outgoing-0 << vary: origin
18:18:05.939 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Connection can be kept alive indefinitely
18:18:05.939 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection [id: 0][route: {}->http://127.0.0.1:15672] can be kept alive indefinitely
18:18:05.939 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {}->http://127.0.0.1:15672][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]
請求返回:405(http://127.0.0.1:15672/api/exchanges)
18:18:05.944 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager is shutting down
18:18:05.944 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: Close connection
18:18:05.945 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager shut down
Disconnected from the target VM, address: '127.0.0.1:15642', transport: 'socket'

我查看前面的請求返回的數據看到如圖返回信息:

提示說頭部允許GET請求,但是我在代碼中我是使用的是Post請求。如下代碼

            String url="http://127.0.0.1:15672/api/exchanges";
            HttpPost httpPost = new HttpPost(url);
            CloseableHttpClient pClient=HttpClients.createDefault();
            CloseableHttpResponse response = null;
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair("encoding", "UTF-8"));
            nvps.add(new BasicNameValuePair("Username", "admin"));
            nvps.add(new BasicNameValuePair("Password", "Adm@ad12"));
            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            response = pClient.execute(httpPost);

我就猜想是不是因爲請求方法不同導致?於是我更換了Post請求爲Get請求後。果然報錯更改爲401,如下:

18:25:01.728 [main] DEBUG org.apache.http.impl.client.TargetAuthenticationStrategy - Challenge for Kerberos authentication scheme not available
18:25:01.728 [main] DEBUG org.apache.http.impl.client.TargetAuthenticationStrategy - Challenge for NTLM authentication scheme not available
18:25:01.728 [main] DEBUG org.apache.http.impl.client.TargetAuthenticationStrategy - Challenge for Digest authentication scheme not available
18:25:01.735 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection [id: 0][route: {}->http://127.0.0.1:15672] can be kept alive indefinitely
18:25:01.735 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {}->http://127.0.0.1:15672][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]
Disconnected from the target VM, address: '127.0.0.1:9713', transport: 'socket'
請求返回:401(http://127.0.0.1:15672/api/exchanges?Username=admin&Password=Adm@ad12)
18:25:01.752 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager is shutting down
18:25:01.753 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: Close connection
18:25:01.753 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager shut down

最後我排除了密碼、賬號名書寫錯誤以後,我通過谷歌抓包發現,如圖:

如圖所示發現原來如果要用HTTP的API獲得RabbitMQ的交換機、隊列等信息時,系統要求使用Basic的HTTP的認證方式。

所以修改了我的代碼如下完整的:

/**
     * 獲得CloseableHttpClient對象,通過basic認證。
     * @param username
     * @param password
     * @return
     */
    private static CloseableHttpClient getBasicHttpClient(String username,String password) {
        // 創建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // 設置BasicAuth
        CredentialsProvider provider = new BasicCredentialsProvider();
        AuthScope scope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM);
        UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username,password);
        provider.setCredentials(scope, credentials);
        httpClientBuilder.setDefaultCredentialsProvider(provider);
        return httpClientBuilder.build();
    }

    /**
     * 根據API獲得相關的MQ信息
     * @param url
     * @param username
     * @param password
     * @return
     */
    private static JSONArray getMQJSONArray(String url,String username,String password) {
        HttpGet httpPost = new HttpGet(url);
        CloseableHttpClient pClient=getBasicHttpClient(username,password);
        CloseableHttpResponse response = null;
        JSONArray jsonArray =null;
        try {
            response = pClient.execute(httpPost);
            StatusLine status = response.getStatusLine();
            int state = status.getStatusCode();
            if (state == HttpStatus.SC_OK) {
                String string = EntityUtils.toString(response.getEntity());
                // 返回來是一個集合,去掉開始的“[”和結尾的“]”;
                String substring = string.substring(1, string.length() - 1);
                jsonArray = JSONArray.fromObject(substring);
            } else {
                System.out.println("請求返回:" + state + "(" + url + ")");
            }
        }catch (Exception e){
            logger.error("地址url:"+url+",異常:"+e.toString());
        } finally {
            closeAll(response,pClient);
        }
        return jsonObject;
    }
    private static void closeAll(CloseableHttpResponse response,CloseableHttpClient pClient){
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            pClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        String url="http://127.0.0.1:15672/api/exchanges";
        String username="admin";
        String password="Adm@ad12";
        JSONArray http = getMQJSONArray(url, username, password);
        System.out.println("http:"+http);
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章