訪問 A → 302 → B,HttpClient 直接返回 B 的內容。但業務常需要知道 **最終落地 URL** (B) 以便記錄、審計、防劫持。
public class HttpClientDemo {
public static void getRedirectInfo() {
HttpClient httpClient = new DefaultHttpClient();
HttpContext context = new BasicHttpContext(); // 關鍵:攜帶狀態
HttpGet get = new HttpGet("https://127.0.0.1:8088/blog/main.jsp");
try {
HttpResponse response = httpClient.execute(get, context); // 傳入 context
// 1. 獲取最終目標主機
HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
// 2. 獲取最終請求 URI (含路徑、查詢參數)
HttpUriRequest realRequest = (HttpUriRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
System.out.println("最終主機: " + targetHost); // https://127.0.0.1:8088
System.out.println("最終 URI: " + realRequest.getURI()); // /blog/admin/login.jsp
// 可選:讀取響應體
HttpEntity entity = response.getEntity();
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
EntityUtils.consume(entity);
}
} catch (Exception e) { e.printStackTrace(); }
finally { httpClient.getConnectionManager().shutdown(); }
}
}
| 常量 | 含義 | 類型 |
|---|---|---|
| ExecutionContext.HTTP_TARGET_HOST | 最終解析的目標主機 (scheme+host+port) | HttpHost |
| ExecutionContext.HTTP_REQUEST | 實際發出的請求對象 (含最終 URI) | HttpUriRequest |
| ExecutionContext.HTTP_RESPONSE | 最終響應對象 | HttpResponse |
| ExecutionContext.HTTP_CONNECTION | 底層連接對象 | HttpConnection |
// 請求前放入
context.setAttribute("my-trace-id", UUID.randomUUID().toString());
// 後續攔截器/處理器取出
String traceId = (String) context.getAttribute("my-trace-id");
HttpContext 是客戶端請求鏈路的「黑盒記錄儀」,善用它能解決重定向追蹤、鏈路追蹤、會話保持等一系列問題。
HttpClientBuilder.create().build() 替代 new DefaultHttpClient();ClassicHttpClient、HttpClientContext,核心思想不變。