《HttpClient官方文檔》1.5 異常處理
1.5. 異常處理
HTTP協議處理器會拋出兩種類型的異常: 一種是I/O失敗的情況下產生的java.io.IOException,比如套接字超時或重置。 另一種是發送HTTP信號失敗情況下的HttpException,比如違反HTTP協議。 通常情況,我們認為I/O錯誤是非致命且可恢複的錯誤,而HTTP協議錯誤則是致命且不能自動恢複的。 請注意,HttpClient將HttpException重新封裝成一個IOException的子類ClientProtocolException,這樣用戶就可以在一個catch代碼塊中同時處理I/O錯誤和違反協議的錯誤。
1.5.1. HTTP 傳輸安全
很重要的一點是,HTTP協議並不適用於所有類型的應用程序。 HTTP是一個簡單的麵相request/response的協議,它的設計初衷是為了支持靜態或動態地生成內容檢索。 它從未打算支持事務操作,比如,當HTTP服務器成功地接收並處理了客戶端發送的請求,生成相應並發送回狀態碼,那麼它會就認為完成了約定的內容。 如果由於讀超時,請求取消或者係統崩潰等原因導致客戶端無法成功接收到響應,那麼服務器不會試圖去回滾事務。如果客戶端決定重試相同的請求,服務器最終將不可避免地多次執行相同的事務。 在某些情況下,這有可能導致應用程序的數據汙染或狀態不一致。 盡管HTTP從未被設計成支持事務處理,但是它仍然可以作為一種在特定條件下滿足特殊任務的傳輸協議。 為了保證HTTP傳輸層的安全性,係統必須保證應用層中的HTTP方法是冪等的。
1.5.2. 冪等方法
HTTP / 1.1規範定義了一個冪等方法[N > 0 的多次請求同單次請求產生的效果一樣(除了錯誤或過期問題),這樣的方法具有“冪等性”的性質]。換句話說,應用程序應該確保處理多次執行含義相同的方法的情況。 比如,應用程序可以通過提供一個獨特的transaction id或者通過其他方式避免執行相同的邏輯操作來實現。 請注意,這個問題並不局限於HttpClient。 基於瀏覽器的應用程序正是受同樣涉及非冪等性的HTTP方法影響。
1.5.3. 異常自動恢複
默認情況下HttpClient嚐試從I/O exception中自動恢複。默認的自動恢複機製隻局限於少數已知的安全的異常。
- HttpClient不會試圖從任何邏輯或HTTP協議錯誤(衍生自HttpException類)中恢複。
- HttpClient將自動重試那些被認為是等冪的方法。
- HttpClient將自動重試那些因傳輸異常而失敗但是HTTP請求仍然會被發送到目標服務器的方法。(即請求還沒有完全被發送到服務器端)
1.5.4. 請求重試處理
為了使自定義異常恢複機製有效,實現了HttpRequestRetryHandler接口。
HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(
IOException exception,
int executionCount,
HttpContext context) {
if (executionCount >= 5) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return false;
}
if (exception instanceof UnknownHostException) {
// Unknown host
return false;
}
if (exception instanceof ConnectTimeoutException) {
// Connection refused
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
}
};
CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(myRetryHandler)
.build();
請注意,為了處理安全自動的重試RFC-2616協議中定義的請求方法GET,HEAD,PUT,DELETE,OPTIONS和TRACE,可以用StandardHttpRequestRetryHandler代替使用默認的。
最後更新:2017-05-19 13:33:29
上一篇:
詳解 UEFI 模式下安裝 Linux
下一篇:
大數據探索:在樹莓派上通過 Apache Spark on YARN 搭建 Hadoop 集群
阿裏雲備案要多久?快速通過阿裏雲APP進行域名備案方法
java數據庫連接池dbcp的使用
性能測試:自建數據庫與RDS性能對比(SQL Server案例排查分析)
android listview 設置點擊效果selector
趣文:程序員/開發人員的真實生活
黑客組織利用El Machete竊取全球政府超過100G數據
《計算機網絡:自頂向下方法(原書第6版)》一1.2 網絡邊緣
如何隱藏 Apache 版本號和其它敏感信息
???????????????Elasticsearch????????????2????????????2.5.2???????????????-??????-????????????-?????????
三星采用A15內核處理器神秘手機現身