如圖所示,我們可以找到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);
}