欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解決RestTemplate 請求url中包含百分號 會被轉義成25的問題

 更新時間:2021年10月28日 11:16:11   作者:toneylyx  
這篇文章主要介紹了解決RestTemplate 請求url中包含百分號 會被轉義成25的問題,具有很好的參考價值,希望對大家有所幫助。

RestTemplate 請求url中包含百分號 會被轉義成25

最初使用RestTemplate 進行遠程調用方法如下:

private String getRemoteData(String url) {
  logger.info("Request URL :" + url + "|");
 
  String resp = rest.getForObject(url, String.class);
 
  logger.info("Response result : " + resp.toString());
  return resp;
 }

但發(fā)現(xiàn)請求結果一直為空。

最后發(fā)現(xiàn)由于我們的業(yè)務場景中,請求參數(shù)包含中文要求按指定規(guī)則轉碼,導致請求url中包含% ,而RestTemplate會自動調用encode方法進行轉義,將%轉義成了%25 。

解決方法

自建URI 傳入:

private String getRemoteData(String url) {
  logger.info("Request URL :" + url + "|");
  String resp = null;
  try {
   URI uri = new URI(url);
   resp = rest.getForObject(uri, String.class);
  } catch (URISyntaxException e) {
   logger.error("Create URI Exception !");
  }
 
  logger.info("Response result : " + resp.toString());
  return resp;
 }

RestTemplate轉碼bug

發(fā)現(xiàn)一個關于HTTP的Get請求的罕見bug。

轉碼問題的背景

需要向tigergraph服務端發(fā)送一個復雜的get請求,參數(shù)只有一個,但是參數(shù)的值是一個復雜json

服務端收到的值始終是不正常的值。觀察發(fā)現(xiàn),不正常地方在于服務端本應解析為空格的地方都變成了加號(+)。

以為是代碼寫得有問題,然后使用HTTPclient的原生的方式發(fā)起請求:

public static String doGet(String url) throws Exception{
        HttpGet get = new HttpGet(url);
        return doMethod(get);
    }

    private static String doMethod(HttpRequestBase method)throws Exception{
        CloseableHttpResponse response = null;
        CloseableHttpClient client;
        HttpClientBuilder hcb = HttpClientBuilder.create();
        HttpRequestRetryHandler hrrh = new DefaultHttpRequestRetryHandler();
        HttpClientBuilder httpClientBuilder = hcb.setRetryHandler(hrrh);
        client = httpClientBuilder.build();
        method.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        method.addHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON);
        RequestConfig.Builder confBuilder = RequestConfig.custom();
        confBuilder.setConnectTimeout(CONNECT_TIMEOUT);
        confBuilder.setConnectionRequestTimeout(REQUEST_TIMEOUT);
        confBuilder.setSocketTimeout(SOCKET_TIMEOUT);
        RequestConfig config = confBuilder.build();
        method.setConfig(config);
        response = client.execute(method);
        int code = response.getStatusLine().getStatusCode();
        String result = EntityUtils.toString(response.getEntity());
        response.close();
        client.close();
        return result;
    }

得到結果還是這個問題,使用Assured測試工具構建http請求也有這問題。

結論

后來仔細檢查了URLEncode.encode方法和RestTemplate源碼實現(xiàn)后,發(fā)現(xiàn)是客戶端的轉碼協(xié)議和服務端的解碼協(xié)議不匹配導致。

經(jīng)反復測試和嚴重,這個問題只有參數(shù)中帶有空格時才會有,其他字符都不有,比如: / * & 這類特殊字符都沒這問題。

最后的解決方案是替換URL串的轉碼后的字符串中的空格為%20,然后使用http client原生的請求方式。

第二個解決方案是使用RestTemplate的UriComponentsBuilder類,使用(builder.build(false).toUri()獲得URL,參數(shù)必須是false才會把空格轉成%20

/** * urlencode轉碼不能隨便用,因為她會把空格轉換成+號,而不是標準的%20字符。 * 對于spring構建的服務端不會有這個問題。但我在tiger服務器上遇到這種問題。 * 所以urlencode只適用于服務端支持的協(xié)議是RFC1738 * 如果服務端只支持RFC 2396標準,那么服務端解碼時,會把加號+當成保留字符,而不轉碼 * */
  @Override
    @SuppressWarnings("all")
    public <Req, Resp> Resp doGet(String url, Req request, Class<Resp> responseType) throws Exception {
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        Map<String, Object> parameters = (Map<String, Object>)request;
        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
            builder.queryParam(entry.getKey(), Objects.toString(entry.getValue(), ""));
        }
        return restTemplate.getForObject(builder.build(false).toUri(), responseType);
    }

為什么會有這個問題?

根源在于Java語言的URLEncode類只能適用于早期的RFC協(xié)議,通常spring開發(fā)的服務端是兼容這種模式的。

新版的RFC協(xié)議會把+號當成關鍵字不再反轉成空格,這通常體現(xiàn)在新技術上,比如目前用的tigergraph圖數(shù)據(jù)庫就有這情形。

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

相關文章

  • springboottest測試依賴和使用方式

    springboottest測試依賴和使用方式

    這篇文章主要介紹了springboottest測試依賴和使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Spring Boot整合Spring Data Jpa代碼實例

    Spring Boot整合Spring Data Jpa代碼實例

    這篇文章主要介紹了Spring Boot整合Spring Data Jpa代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • 深入理解java的spring-ioc的使用

    深入理解java的spring-ioc的使用

    這篇文章主要介紹了java的spring-ioc的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • Spring?Security?過濾器注冊脈絡梳理

    Spring?Security?過濾器注冊脈絡梳理

    這篇文章主要介紹了Spring?Security過濾器注冊脈絡梳理,Spring?Security在Servlet的過濾鏈中注冊了一個過濾器FilterChainProxy,它會把請求代理到Spring?Security自己維護的多個過濾鏈,每個過濾鏈會匹配一些URL,如果匹配則執(zhí)行對應的過濾器
    2022-08-08
  • 如何在Spring?Boot中使用OAuth2認證和授權

    如何在Spring?Boot中使用OAuth2認證和授權

    這篇文章主要介紹了如何在Spring?Boot中使用OAuth2認證和授權的相關資料,OAuth2.0是一種開放的授權協(xié)議,它允許用戶授權第三方應用訪問其賬戶(或資源),而無需共享其用戶賬戶憑據(jù),需要的朋友可以參考下
    2023-12-12
  • springboot自動重啟的簡單方法

    springboot自動重啟的簡單方法

    Springboot提供了熱部署的方式,當發(fā)現(xiàn)任何類發(fā)生了改變,馬上通過JVM類加載的方式,加載最新的類到虛擬機中。這篇文章主要介紹了springboot自動重啟的實現(xiàn)方法,需要的朋友可以參考下
    2018-04-04
  • SpringCloud Config連接git與數(shù)據(jù)庫流程分析講解

    SpringCloud Config連接git與數(shù)據(jù)庫流程分析講解

    springcloud config是一個解決分布式系統(tǒng)的配置管理方案。它包含了 client和server兩個部分,server端提供配置文件的存儲、以接口的形式將配置文件的內容提供出去,client端通過接口獲取數(shù)據(jù)、并依據(jù)此數(shù)據(jù)初始化自己的應用
    2022-12-12
  • java+mysql實現(xiàn)商品搶購功能

    java+mysql實現(xiàn)商品搶購功能

    這篇文章主要為大家詳細介紹了java+mysql實現(xiàn)商品搶購功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Spring Security學習之rememberMe自動登錄的實現(xiàn)

    Spring Security學習之rememberMe自動登錄的實現(xiàn)

    這篇文章主要給大家介紹了關于Spring Security學習之rememberMe自動登錄的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-06-06
  • Java并發(fā)編程示例(二):獲取和設置線程信息

    Java并發(fā)編程示例(二):獲取和設置線程信息

    這篇文章主要介紹了Java并發(fā)編程示例(二):獲取和設置線程信息,本文是系列文章的第二篇,本文著重講解Thread類的幾個重要屬性,需要的朋友可以參考下
    2014-12-12

最新評論