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

SpringBoot之RestTemplate在URL中轉(zhuǎn)義字符的問題

 更新時間:2023年06月26日 08:57:33   作者:MLn0829  
這篇文章主要介紹了SpringBoot之RestTemplate在URL中轉(zhuǎn)義字符的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

RestTemplate在URL中轉(zhuǎn)義字符的問題

相同代碼在不同SpringBoot版本中使用RestTemplate請求時遇到的問題:

Map<String, Object> param = new HashMap<String, Object>();
            param.put("version","2.0.0");
            String userSing = sign(param);
            param.put("user_sign", userSing);
            logger.info("簽名:" + userSing);
            StringBuilder paramStr = new StringBuilder("?");
            for(Map.Entry<String, Object> entry : param.entrySet()){
                paramStr.append(entry.getKey()).append("=")
                        .append(entry.getValue() == null ? "" : String.valueOf(entry.getValue()))
                        .append("&");
            }
            paramStr.deleteCharAt(paramStr.length() - 1);
            logger.info("入?yún)?" + paramStr.toString());
            RestTemplate restTemplate = new RestTemplate();
            String jsonStr = restTemplate.getForObject(sendMessagesUrl + paramStr.toString(), String.class);
            logger.info("響應(yīng)值:" + jsonStr);

下面截圖為springboot1.5.3 RestTemplate request log

springboot1.5.3 RestTemplate request log

下面截圖為springboot2.1.7 RestTemplate request log

springboot2.1.7 RestTemplate request log

在這兩份log中可以看到user_sign對應(yīng)的value值中的 + 是特殊的字符,1.0版本的被轉(zhuǎn)義為: %2B2.0版本沒有被轉(zhuǎn)義,最終2.0版本程序的RestTemplate請求第三方在簽名解碼時校驗不通過。

1.嘗試與分析

根據(jù)上述信息我們可以圈定問題的范圍,= 有被轉(zhuǎn)碼,說明可能是在RestTemplate中url參數(shù)的構(gòu)建轉(zhuǎn)碼的方式上與httpClient有什么不通,嘗試進行各類處理方法。

主要使用的方式有:

  • UriComponent構(gòu)建uri(未解決)
  • 構(gòu)建如下RestTemplateConfig(未解決)
public class RestTemplateConfig {
    @Bean
    RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setReadTimeout(40000);
        requestFactory.setConnectTimeout(40000);
        // 添加轉(zhuǎn)換器
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
        messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
        messageConverters.add(new FormHttpMessageConverter());
        messageConverters.add(new MappingJackson2HttpMessageConverter());
        RestTemplate restTemplate = new RestTemplate(messageConverters);
        restTemplate.setRequestFactory(requestFactory);
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
        return restTemplate;
    }
}

2.跟蹤RestTemplate源碼

RestTemplate源碼

debug到這里時發(fā)現(xiàn)user_sign被轉(zhuǎn)義了但 + 沒有變。

URLDecode

這時URLDecoder.decode("/QaNSBls/U8ciXEWaCWtmeMK6+w%3D")會發(fā)現(xiàn) + 變成了 空格,導致第三方在簽名解碼時校驗不通過。

isAllowed

再次通過比較會發(fā)現(xiàn)StringBoot2.0版本對應(yīng)的URL轉(zhuǎn)碼 + 不會被解析。

經(jīng)過多次百度有看到如下:

根據(jù) RFC 3986 加號等符號的確實可以出現(xiàn)在參數(shù)中的,而且不需要編碼,有問題的在于服務(wù)端的解析沒有與時俱進

3.解決問題

最后解決一些這個問題,當使用RestTemplate發(fā)起請求,如果請求參數(shù)中有需要url編碼時

通過如下兩種方式解決:

1.不希望出現(xiàn)問題的使用姿勢應(yīng)傳入URI對象而不是字符串,修改RestTemplate請求方法入?yún)⒌?code>String url 修改為 URI url。

2.修改入?yún)⒕幋a格式URLEncoder.encode(user_sign, "UTF-8"),然后在構(gòu)建RestTemplate時,

Map<String, Object> param = new HashMap<String, Object>();
        StringBuilder paramStr = new StringBuilder("?");
            param.put("version","xxxxx");
            param.put("time","xxxxx");
            //轉(zhuǎn)化成md5生產(chǎn)密鑰
            String userSing  = sign(param);
            String userSign = URLEncoder.encode(userSing, "UTF-8");
            param.put("user_sign", userSign);
            for(Map.Entry<String, Object> entry : param.entrySet()){
                paramStr.append(entry.getKey()).append("=")
                        .append(entry.getValue() == null ? "" : String.valueOf(entry.getValue()))
                        .append("&");
            }
            paramStr.deleteCharAt(paramStr.length() - 1);
            CloseableHttpClient httpClient = HttpClientUtils.acceptsUntrustedCertsHttpClient();
            HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
            RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
            DefaultUriBuilderFactory uriFactory = new DefaultUriBuilderFactory();
            uriFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
            restTemplate.setUriTemplateHandler(uriFactory);
            String smsJsonStr = restTemplate.getForObject(SMSURL + paramStr.toString(), String.class);
            Map<String, Object> map = GsonUtil.gsonToMap(smsJsonStr);

小結(jié)

注意SpringBoot2.0版本的url參數(shù)編碼,默認只會針對 = 和 & 進行處理;為了兼容我們一般的后端的url編解碼處理在需要編碼參數(shù)時,

個人建議盡量不要使用Spring默認的方式,不然接收到數(shù)據(jù)會和預期的不一致。

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

相關(guān)文章

  • RocketMQ重試機制及消息冪代碼實例解析

    RocketMQ重試機制及消息冪代碼實例解析

    這篇文章主要介紹了RocketMQ重試機制及消息冪代碼實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • Spring零基礎(chǔ)入門IOC

    Spring零基礎(chǔ)入門IOC

    IoC就是比方說有一個類,我們想要調(diào)用類里面的方法(不是靜態(tài)方法),就要創(chuàng)建該類的對象,使用對象調(diào)用方法來實現(xiàn)。但對于Spring來說,Spring創(chuàng)建對象的過程,不是在代碼里面實現(xiàn)的,而是交給Spring來進行配置實現(xiàn)的
    2022-08-08
  • 簡單聊一聊Spring中Bean別名的處理原理

    簡單聊一聊Spring中Bean別名的處理原理

    今天來和小伙伴們聊一聊 Spring 中關(guān)于 Bean 別名的處理邏輯,別名,顧名思義就是給一個 Bean 去兩個甚至多個名字,整體上來說,在 Spring 中,有兩種不同的別名定義方式,感興趣的小伙伴跟著小編一起來看看吧
    2023-09-09
  • mybatis高級映射一對多查詢實現(xiàn)代碼

    mybatis高級映射一對多查詢實現(xiàn)代碼

    本篇文章主要介紹了mybatis高級映射一對多查詢實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • java基于QuartzJobBean實現(xiàn)定時功能的示例代碼

    java基于QuartzJobBean實現(xiàn)定時功能的示例代碼

    QuartzJobBean是Quartz框架中的一個抽象類,用于定義和實現(xiàn)可由Quartz調(diào)度的作業(yè),本文主要介紹了java基于QuartzJobBean實現(xiàn)定時功能的示例代碼,具有一定的參考價值,感興趣可以了解一下
    2023-09-09
  • Springboot mybatisplus如何解決分頁組件IPage失效問題

    Springboot mybatisplus如何解決分頁組件IPage失效問題

    這篇文章主要介紹了Springboot mybatisplus如何解決分頁組件IPage失效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 關(guān)于Java中@SuppressWarnings的正確使用方法

    關(guān)于Java中@SuppressWarnings的正確使用方法

    這篇文章主要介紹了關(guān)于Java中@SuppressWarnings的正確使用方法,@SuppressWarnings注解主要用在取消一些編譯器產(chǎn)生的警告對代碼左側(cè)行列的遮擋,有時候這會擋住我們斷點調(diào)試時打的斷點,需要的朋友可以參考下
    2023-05-05
  • MyBatis-Plus找不到Mapper.xml文件的幾種解決方法

    MyBatis-Plus找不到Mapper.xml文件的幾種解決方法

    mybatis-plus今天遇到一個問題,就是mybatis 沒有讀取到mapper.xml 文件,所以下面這篇文章主要給大家介紹了關(guān)于MyBatis-Plus找不到Mapper.xml文件的幾種解決方法,需要的朋友可以參考下
    2022-06-06
  • SpringBoot集成RocketMQ發(fā)送事務(wù)消息的原理解析

    SpringBoot集成RocketMQ發(fā)送事務(wù)消息的原理解析

    RocketMQ 的事務(wù)消息提供類似 X/Open XA 的分布事務(wù)功能,通過事務(wù)消息能達到分布式事務(wù)的最終一致,這篇文章主要介紹了SpringBoot集成RocketMQ發(fā)送事務(wù)消息,需要的朋友可以參考下
    2022-06-06
  • Java使用Apache POI庫讀取Excel表格文檔的示例

    Java使用Apache POI庫讀取Excel表格文檔的示例

    POI庫是Apache提供的用于在Windows下讀寫各類微軟Office文檔的Java庫,這里我們就來看一下Java使用Apache POI庫讀取Excel表格文檔的示例:
    2016-06-06

最新評論

南京市| 阿合奇县| 邵东县| 镇宁| 乐昌市| 得荣县| 盐亭县| 虎林市| 成武县| 林芝县| 盈江县| 平山县| 容城县| 修水县| 黄大仙区| 永安市| 闻喜县| 崇礼县| 如皋市| 仲巴县| 庆城县| 南华县| 高陵县| 齐河县| 新乡县| 扬中市| 新兴县| 郸城县| 晋江市| 中江县| 西乌| 肇庆市| 霍邱县| 靖西县| 桂东县| 铁岭县| 常宁市| 财经| 渝北区| 鹿泉市| 正镶白旗|