問題描述:
使用HttpClient進行http請求,每次請求隨機使用一個target host進行請求。
發http請求的時候,一般會配置資料來源,設定ClientPNames.DEFAULT_HOST,這樣在請求的時候目標機器host和連接埠就是配置的ClientPNames.DEFAULT_HOST。但是不能每次請求ClientPNames.DEFAULT_HOST,因為一個httpclient就對應一個ClientPNames.DEFAULT_HOST,就無法針對一次request進行目標host的修改。
例如:
HttpGet httpGet = new HttpGet(url);
在進行請求時,httpGet作為參數執行execute,此時url是相對路徑,httpclient會將defaulthost+uri拼接為完整的請求地址進行請求。
看HttpClient的原始碼可以發現URI是個線索,在execute方法中會判斷URI中設定的是否是絕對路徑還是相對路徑,如果是相對路徑時httpclient會將defaulthost+uri拼接為完整的請求地址。如果URI中設定了scheme並且URI配置了host就會用URI完整的絕對路徑作為請求地址。判斷邏輯如下
public final HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException { if (request == null) { throw new IllegalArgumentException ("Request must not be null."); } return execute(determineTarget(request), request, context);}private static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException { // A null target may be acceptable if there is a default target. // Otherwise, the null target is detected in the director. HttpHost target = null; URI requestURI = request.getURI(); if (requestURI.isAbsolute()) { target = URIUtils.extractHost(requestURI); if (target == null) { throw new ClientProtocolException( "URI does not specify a valid host name: " + requestURI); } } return target;}分析完就找到了方法解決問題了,在請求時設定URI即可,要注意的是build URI的時候要配置scheme參數才會生效。