最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決使用RestTemplate時報錯RestClientException的問題

 更新時間:2021年08月19日 09:54:48   作者:墨一般的白色  
這篇文章主要介紹了解決使用RestTemplate時報錯RestClientException的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

使用RestTemplate時報錯RestClientException

這是自己封裝的一個發(fā)送請求的方法

public  Map<String, Object> sendRequest(Map<String, Object> body,String sessionId,String url) {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new BdMappingJackson2HttpMessageConverter());
        Map<String, Object> map = new HashMap<>();
        try {
            ParameterizedTypeReference<Map<String, Object>> typeRef = new ParameterizedTypeReference<Map<String, Object>>() {
            };
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.set("cookie", "SESSION="+sessionId);
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(body,headers);
            ResponseEntity<Map<String, Object>> responseEntity = restTemplate.exchange(url, HttpMethod.POST,
                    requestEntity,typeRef);
            map = responseEntity.getBody();
            log.info(map.toString());
        } catch (HttpStatusCodeException e) {
            log.error(e.getResponseBodyAsString(), e);
            map = JsonUtil.toMap(e.getResponseBodyAsString());
        }
        return map;
    }

這是自定義的一個http信息Converter

public class BdMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
    public BdMappingJackson2HttpMessageConverter(){
        List<MediaType> mediaTypes = new ArrayList<>();
        mediaTypes.add(MediaType.TEXT_HTML);
        mediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
        setSupportedMediaTypes(mediaTypes);
    }
}

我遇到的第一個問題是這樣的

Could not write request: no suitable HttpMessageConverter found for request type [java.util.HashMap] and content type [application/octet-stream]

意思大概是無法寫入請求:找不到適用于請求類型[java.util.HashMap]和內(nèi)容類型[application/octet stream]的HttpMessageConverter

它默認只處理application/json:JSON數(shù)據(jù)格式,這個二進制數(shù)據(jù)流格式不支持,所以我在那個自定義的Converter加上去了。

緊接著又遇到第二個問題

Could not extract response: no suitable HttpMessageConverter found for response type [java.util.Map<java.lang.String, java.lang.Object>] and content type [text/xml;charset=UTF-8]

無法提取響應(yīng):找不到適合于響應(yīng)類型[java.util.Map<java.lang.String,java.lang.Object>]和內(nèi)容類型[textml/charset=UTF-8]的HttpMessageConverter

這是那邊回調(diào)過來的Content-Type類型是text/xml它同樣解析不了,所以我把這個也加上去了,至此就ok了。

常見的Content-Type類型:

  • text/html:HTML格式
  • text/plain:純文本格式
  • image/png:png圖片格式
  • application/json:JSON數(shù)據(jù)格式
  • application/octet-stream:二進制流數(shù)據(jù)
  • application/x-www-form-urlencoded:表單中默認的encType,表單數(shù)據(jù)被編碼為key/value格式發(fā)送到服務(wù)器
  • multipart/form-data:需要在表單中進行文件上傳時,就需要使用該格式

RestTemplate的錯誤處理

我們的項目屬于微服務(wù)架構(gòu),兩個基礎(chǔ)的服務(wù)分別是網(wǎng)關(guān)和認證鑒權(quán)服務(wù)。

在前端訪問后臺服務(wù)的時候,都經(jīng)過網(wǎng)關(guān)轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)之前會進行鑒權(quán)認證,根據(jù)鑒權(quán)結(jié)果判斷是否可以進行相應(yīng)的請求轉(zhuǎn)發(fā)。

問題描述

認證鑒權(quán)服務(wù)中,判斷Token對應(yīng)的人員是否有相應(yīng)的權(quán)限,如果沒有權(quán)限,返回401狀態(tài)碼并在響應(yīng)體中傳回錯誤信息。

網(wǎng)關(guān)與鑒權(quán)服務(wù)之間的服務(wù)調(diào)用通過RestTemplate進行(可以考慮轉(zhuǎn)為Feign做聲明式的服務(wù)調(diào)用),然而如果鑒權(quán)服務(wù)返回401的情況下,網(wǎng)關(guān)服務(wù)直接報出HttpClientErrorException,讓人一頭霧水。

實際上,答案都在源碼中,看一下RestTemplate的源碼就知曉了。

ErrorHandler

在RestTemplate中,有一個成員變量ResponseErrorHandler。

ResponseErrorHandler是一個接口,包括兩個方法:

public interface ResponseErrorHandler {
    boolean hasError(ClientHttpResponse var1) throws IOException;
    void handleError(ClientHttpResponse var1) throws IOException;
}

這個接口有一個默認實現(xiàn)DefaultResponseErrorHandler。該方法中,判斷是否發(fā)生error的方法hasError最終調(diào)用的方法如下:

protected boolean hasError(HttpStatus statusCode) {
        return statusCode.series() == Series.CLIENT_ERROR || statusCode.series() == Series.SERVER_ERROR;
    }

很明顯,根據(jù)響應(yīng)狀態(tài)嗎為4xx或者5xx來認定發(fā)生了錯誤。而錯誤處理在handleError中:

public void handleError(ClientHttpResponse response) throws IOException {
        HttpStatus statusCode = this.getHttpStatusCode(response);
        switch(null.$SwitchMap$org$springframework$http$HttpStatus$Series[statusCode.series().ordinal()]) {
        case 1:
            throw new HttpClientErrorException(statusCode, response.getStatusText(), response.getHeaders(), this.getResponseBody(response), this.getCharset(response));
        case 2:
            throw new HttpServerErrorException(statusCode, response.getStatusText(), response.getHeaders(), this.getResponseBody(response), this.getCharset(response));
        default:
            throw new RestClientException("Unknown status code [" + statusCode + "]");
        }
    }

可見,4xx的狀態(tài)嗎會拋出HttpClientErrorException;5xx的狀態(tài)碼會拋出HttpServerErrorException。這也就是我們一開始遇到的問題的原因所在了。而在handleError中,執(zhí)行了response.getBody(),這就導(dǎo)致我們后續(xù)獲取不到響應(yīng)體了,如果要獲取的話,需要進行自定義相關(guān)處理。

解決辦法

如果RestTemplate的應(yīng)用場景比較統(tǒng)一,可以自定義ResponseErorHandler(派生自DefaultResponseErrorHandler)來接管錯誤處理,進行自己想要的處理。

而我們的網(wǎng)關(guān)中,對于頁面跳轉(zhuǎn)類的請求和Rest API類的請求,處理辦法顯然是不一樣的。所以最終處理是catch異常,然后進行重定向的處理操作。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Springboot實現(xiàn)多數(shù)據(jù)源切換詳情

    Springboot實現(xiàn)多數(shù)據(jù)源切換詳情

    這篇文章主要介紹了Springboot實現(xiàn)多數(shù)據(jù)源切換詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的朋友可以參考一下
    2022-09-09
  • Java中如何給List進行排序(這7種方法輕松實現(xiàn))

    Java中如何給List進行排序(這7種方法輕松實現(xiàn))

    在Java項目中可能會遇到給出一些條件,將List元素按照給定條件進行排序的情況,這篇文章主要給大家介紹了關(guān)于Java中如何給List進行排序的相關(guān)資料,通過文中介紹的這7種方法可以輕松實現(xiàn),需要的朋友可以參考下
    2023-10-10
  • Java實現(xiàn)滑動驗證碼生成(后端工具類)

    Java實現(xiàn)滑動驗證碼生成(后端工具類)

    這篇文章主要為大家詳細介紹了Java實現(xiàn)滑動驗證碼生成功能中的后端工具類部分,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-10-10
  • Java解決前端數(shù)據(jù)處理及亂碼問題

    Java解決前端數(shù)據(jù)處理及亂碼問題

    大伙們有沒有遇到數(shù)據(jù)亂碼的問題,真的是讓人心情煩躁,今天就來教下大家數(shù)據(jù)怎么傳輸?shù)角岸艘约皝y碼問題怎么解決的,需要的朋友可以參考一下
    2021-12-12
  • Kafka中Producer和Consumer的作用詳解

    Kafka中Producer和Consumer的作用詳解

    這篇文章主要介紹了Kafka中Producer和Consumer的作用詳解,Kafka是一個分布式的流處理平臺,它的核心是消息系統(tǒng),Producer是Kafka中用來將消息發(fā)送到Broker的組件之一,它將消息發(fā)布到主題,并且負責(zé)按照指定的分區(qū)策略將消息分配到對應(yīng)的分區(qū)中,需要的朋友可以參考下
    2023-12-12
  • Java DriverManager.getConnection()獲取數(shù)據(jù)庫連接

    Java DriverManager.getConnection()獲取數(shù)據(jù)庫連接

    這篇文章主要介紹了Java DriverManager.getConnection()獲取數(shù)據(jù)庫連接,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • SpringBoot訪問靜態(tài)資源的配置及順序說明

    SpringBoot訪問靜態(tài)資源的配置及順序說明

    這篇文章主要介紹了SpringBoot訪問靜態(tài)資源的配置及順序說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java基于redis和mysql實現(xiàn)簡單的秒殺(附demo)

    Java基于redis和mysql實現(xiàn)簡單的秒殺(附demo)

    這篇文章主要介紹了Java基于redis和mysql實現(xiàn)簡單的秒殺(附demo),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Java線程關(guān)閉的3種方法

    Java線程關(guān)閉的3種方法

    這篇文章介紹了Java線程關(guān)閉的3種方法,有需要的朋友可以參考一下
    2013-10-10
  • Java單元測試Mockito的使用詳解

    Java單元測試Mockito的使用詳解

    Mockito是一個強大的mock工具,本文將重點講述Mockito的基本使用及注意事項,以及Controller測試用例,本文通過示例代碼給大家介紹的非常詳細,需要的朋友參考下吧
    2021-07-07

最新評論

常宁市| 宝应县| 开鲁县| 莱芜市| 全椒县| 铜梁县| 浮山县| 新巴尔虎右旗| 临沂市| 砀山县| 昌乐县| 扬中市| 融水| 高州市| 龙江县| 二连浩特市| 天峻县| 陇川县| 宁波市| 会宁县| 吴堡县| 闽侯县| 开封市| 日喀则市| 兰州市| 子洲县| 临西县| 通州区| 驻马店市| 拉萨市| 类乌齐县| 大荔县| 介休市| 宣化县| 黑水县| 乌恰县| 浪卡子县| 巴林右旗| 和龙市| 安吉县| 大理市|