我們的專案屬於微服務架構,兩個基礎的服務分別是閘道器和認證鑑權服務。
在前端訪問後台服務的時候,都經過閘道器**,**之前會進行鑑權認證,根據鑑權結果判斷是否可以進行相應的請求**。
認證鑑權服務中,判斷token對應的人員是否有相應的許可權,如果沒有許可權,返回401狀態碼並在響應體中傳回錯誤資訊。
閘道器與鑑權服務之間的服務呼叫通過resttemplate進行(可以考慮轉為feign做宣告式的服務呼叫),然而如果鑑權服務返回401的情況下,閘道器服務直接報出httpclienterrorexception,讓人一頭霧水。
實際上,答案都在原始碼中,看一下resttemplate的原始碼就知曉了。
在resttemplate中,有乙個成員變數responseerrorhandler。
responseerrorhandler是乙個介面,包括兩個方法:
public
inte***ce
responseerrorhandler
這個介面有乙個預設實現defaultresponseerrorhandler。該方法中,判斷是否發生error的方法haserror最終呼叫的方法如下:
protected
boolean
haserror(httpstatus statuscode)
很明顯,根據響應狀態嗎為4xx或者5xx來認定發生了錯誤。而錯誤處理在handleerror中:
}可見,4xx的狀態嗎會丟擲httpclienterrorexception;5xx的狀態碼會丟擲httpservererrorexception。這也就是我們一開始遇到的問題的原因所在了。而在handleerror中,執行了response.getbody(),這就導致我們後續獲取不到響應體了,如果要獲取的話,需要進行自定義相關處理。
如果resttemplate的應用場景比較統一,可以自定義responseerorhandler(派生自defaultresponseerrorhandler)來接管錯誤處理,進行自己想要的處理。
而我們的閘道器中,對於頁面跳轉類的請求和rest api類的請求,處理辦法顯然是不一樣的。所以最終處理是catch異常,然後進行重定向的處理操作。
高併發下restTemplate的錯誤分析
org.apache.http.conn.connectionpooltimeoutexception timeout waiting for connection此問題很明顯是連線等待超時,而且是從連線池中獲取的連線。那麼就有乙個很詫異的問題,這裡哪來的連線池呢?然後我去跟蹤resttemplat...
Spring中RestTemplate的使用
1 帶引數的get請求 請求url示例 http localhost 8080 test sendsms?phone 手機號 msg 簡訊內容 錯誤使用 autowired private restoperations restoperations public void test throws e...
對Spring 的RestTemplate進行包裝
spring的resttemplate及大地簡化了rest client的開發,但每次還要編寫大量的模板 不夠簡潔。我對他進行了一次包裝,採用介面來宣告rest介面,使用annotation對inte ce的方法進行標註。如下宣告乙個rest介面 介面必須繼承baserestclient,提供了乙個...