Http請求中的特殊字符

問題

一個 springboot 應用,包含如下 controller

@RestController
public class DemoController {@GetMapping("/get")public ResponseEntity<String> get(@RequestParam(value = "cid2") String cid2)

準備測試數據

String cid2 = "1;MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoJDsA9HldKEk8i/lbRxS8E13HlCBjg63CrDLF6ieQT+h7K9eRS5jH0VgYXLmWJLOnGLrH1324JaEYHbTmZgpVw==;eWxJY0hrdlBPYVMz;MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpto5kN5HEx/OvVTV2ux08EvneYb+cNx4g9G7ajgH41gBCl7G5JkbaYA7Wf9DxOks3Syu/NJPwhjbOz32L+BfTA==;hcHB3S1D5hgfe5Ar9DUKqW3SeCrvAgeXzt7RldZTh/qWCouFW6NqEZfycxe9Tqi9ehemNc1cMaAtAsC2Ng34hZsEN/cdyqGRcRTbYSpEtdL3GVbyIF5S9hTYD9wcvUMMhsnFIfUMZD0=";

發起請求

String url = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/get").queryParam("cid2", cid2).toUriString();
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);

發現問題,controller 接收到的數據為

1;MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoJDsA9HldKEk8i/lbRxS8E13HlCBjg63CrDLF6ieQT h7K9eRS5jH0VgYXLmWJLOnGLrH1324JaEYHbTmZgpVw==;eWxJY0hrdlBPYVMz;MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpto5kN5HEx/OvVTV2ux08EvneYb cNx4g9G7ajgH41gBCl7G5JkbaYA7Wf9DxOks3Syu/NJPwhjbOz32L BfTA==;hcHB3S1D5hgfe5Ar9DUKqW3SeCrvAgeXzt7RldZTh/qWCouFW6NqEZfycxe9Tqi9ehemNc1cMaAtAsC2Ng34hZsEN/cdyqGRcRTbYSpEtdL3GVbyIF5S9hTYD9wcvUMMhsnFIfUMZD0=

對比發現其中的加號變成了空格,而我們希望傳遞到服務端的是依然是加號。


?

原因分析

根據 URL 編碼的規范,空格字符在 URL 查詢字符串中通常會被編碼為 +。這意味著當發送一個 URL 請求并將 + 作為查詢參數時,瀏覽器和服務器會認為 + 是空格的替代符號。

舉個例子:

假設你傳遞的 URL 是:Example Domain,param=hello+world 中的 + 會被自動解碼為一個空格,最終得到的參數值就是 hello world,而不是原始的 hello+world

解決方法

通過 URLEncoder 進行編碼

Java 的 URLEncoder 可以將特殊字符(如 ;, /, +, =, %)轉義成 URL 編碼的格式。例如,空格被編碼為 +,而其他特殊字符會轉換成以 % 開頭的編碼形式。

客戶端預先編碼,得到:

1%3BMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoJDsA9HldKEk8i%2FlbRxS8E13HlCBjg63CrDLF6ieQT%2Bh7K9eRS5jH0VgYXLmWJLOnGLrH1324JaEYHbTmZgpVw%3D%3D%3BeWxJY0hrdlBPYVMz%3BMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpto5kN5HEx%2FOvVTV2ux08EvneYb%2BcNx4g9G7ajgH41gBCl7G5JkbaYA7Wf9DxOks3Syu%2FNJPwhjbOz32L%2BBfTA%3D%3D%3BhcHB3S1D5hgfe5Ar9DUKqW3SeCrvAgeXzt7RldZTh%2FqWCouFW6NqEZfycxe9Tqi9ehemNc1cMaAtAsC2Ng34hZsEN%2FcdyqGRcRTbYSpEtdL3GVbyIF5S9hTYD9wcvUMMhsnFIfUMZD0%3D

服務端接受到(觀察以下數據可以發現%在傳輸之前再次被編碼為%25):

1%253BMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoJDsA9HldKEk8i%252FlbRxS8E13HlCBjg63CrDLF6ieQT%252Bh7K9eRS5jH0VgYXLmWJLOnGLrH1324JaEYHbTmZgpVw%253D%253D%253BeWxJY0hrdlBPYVMz%253BMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpto5kN5HEx%252FOvVTV2ux08EvneYb%252BcNx4g9G7ajgH41gBCl7G5JkbaYA7Wf9DxOks3Syu%252FNJPwhjbOz32L%252BBfTA%253D%253D%253BhcHB3S1D5hgfe5Ar9DUKqW3SeCrvAgeXzt7RldZTh%252FqWCouFW6NqEZfycxe9Tqi9ehemNc1cMaAtAsC2Ng34hZsEN%252FcdyqGRcRTbYSpEtdL3GVbyIF5S9hTYD9wcvUMMhsnFIfUMZD0%253D

服務端要對接收到的數據 decode 1 次才能得到客戶端預先編碼后的數據,decode 2 次才能獲得我們想要傳輸的帶特殊符號的數據。


?

POST 請求傳遞特殊字符

POST 請求中,數據被發送到請求體 body,而不是 URL 中,因此特殊字符不會被編碼,以下兩種方式都可以。

application/json

headers.setContentType(MediaType.APPLICATION_JSON);
Map<String, String> body = new HashMap<>();
body.put("cid2", cid2);RequestEntity<Map> requestEntity = new RequestEntity<>(body,headers,HttpMethod.POST,URI.create("http://localhost:8080/post")
);ResponseEntity<String> exchange = restTemplate.exchange(requestEntity, String.class);

application/x-www-form-urlencoded

headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("param", cid2);RequestEntity<MultiValueMap<String, String>> requestEntity = new RequestEntity<>(formData,headers,HttpMethod.POST,URI.create("http://localhost:8080/submit")
);ResponseEntity<String> exchange = restTemplate.exchange(requestEntity, String.class);


?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89511.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89511.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89511.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

告別手動報表開發!描述數據維度,AI 自動生成 SQL 查詢 + Java 導出接口

Java 開發中&#xff0c;報表模塊往往是 “隱形耗時大戶”—— 產品經理要 “按地區、月份統計訂單量”&#xff0c;開發者需先編寫 SQL 查詢&#xff0c;再手動開發導出接口&#xff0c;稍作調整又要重新調試&#xff0c;耗費大量時間在重復勞動上。飛算 JavaAI 通過 “數據維…

函數設計測試用例

//歸并排序:public static void mergeSort(int[] a,int left,int right){if(left > right)return;int mid left(right -left)/2;mergeSort(a,left,mid);mergeSort(a,mid1,right);int[] tmp new int[a.length];int l left,r mid1,k left;while(l<mid && r<…

Vmware虛擬機使用僅主機模式共享物理網卡訪問互聯網

一、概述 Vmware虛擬機網卡模式有三種&#xff1a;橋接模式、僅主機模式、NAT模式。默認情況下&#xff0c;Vmware虛擬機使用僅主機模式不能訪問互聯網。因此&#xff0c;虛擬機可以共享宿主機的物理網卡訪問互聯網。 三種網卡模式的區別二、Vmware網絡設置 2.1、調整虛擬網絡 …

聲畫同步!5 個音視頻素材適配的網站,創作更和諧

視頻畫面和背景音樂不搭&#xff1f;音效和動作不同步&#xff1f;好的作品&#xff0c;聲音和畫面必須像齒輪一樣咬合。這 5 個專注 “聲畫同步” 的素材網站&#xff0c;能讓音視頻素材精準匹配&#xff0c;從旋律到節奏&#xff0c;從音效到畫面&#xff0c;都默契十足&…

13.多種I/O函數

前言 之前的示例中&#xff0c;基于Linux的使用read&write函數完成數據I/O&#xff0c;基于Windows的則使用send&recv函數。這次的Linux示例也將使用send& recv函數&#xff0c;并講解其與read&write函數相比的優點。還將介紹幾種其他的I/O函數。 一、send &am…

設計模式五:橋模式(Bridge Pattern)

橋模式是一種結構型設計模式&#xff0c;它將抽象部分與其實現部分分離&#xff0c;使它們可以獨立變化。這種模式通過提供橋梁結構將抽象和實現解耦。橋模式的結構橋模式包含以下主要角色&#xff1a;Abstraction&#xff08;抽象類&#xff09;&#xff1a;定義抽象接口&…

深入理解設計模式之模板模式:優雅地定義算法骨架

在軟件開發中&#xff0c;我們經常會遇到這樣的情況&#xff1a;多個類執行相似的操作流程&#xff0c;但每個類在流程的某些步驟上有自己特定的實現。如果為每個類都完整地編寫整個流程&#xff0c;會導致大量重復代碼&#xff0c;且難以維護。這時候&#xff0c;模板模式&…

基于單片機寵物喂食器/智能寵物窩/智能飼養

傳送門 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目速選一覽表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目功能速覽 概述 深夜加班時&#xff0c;你是否擔心家中寵物餓肚子&#xff1f;出差旅途中&#xff0c;是否焦慮寵…

靜態補丁腳本 - 修改 libtolua.so

直接改arm64的so&#xff0c; 使用python腳本。#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 靜態補丁腳本 - 修改 libtolua.so 主要功能&#xff1a; 1. 修改 luaL_loadbuffer 函數&#xff0c;將跳轉目標從 luaL_loadbufferx 改為 luaL_loadfilex 2. …

2-大語言模型—理論基礎:詳解Transformer架構的實現(2)

目錄 1-大語言模型—理論基礎&#xff1a;詳解Transformer架構的實現(1)-CSDN博客https://blog.csdn.net/wh1236666/article/details/149443139?spm1001.2014.3001.5502 2.3、殘差連接和層歸一化 2.3.1、什么是層歸一化&#xff1f; 2.3.2、層歸一化的核心特點&#xff08…

SmartX 用戶建云實踐|富士康:基于榫卯企業云平臺構建分布式云,支撐全球多地工廠重要產線

作為全球最大的電子科技智造服務商&#xff0c;富士康集團在全球范圍內構建生產制造網絡。為實現多廠區統一管理與降本增效&#xff0c;在逐步替代 VMware 虛擬化架構的過程中&#xff0c;富士康對比了自研 OpenStack Ceph 平臺和 SmartX 超融合方案&#xff0c;最終選擇基于 …

ADC選型設計

1、最大擺伏FSR&#xff1a; 0 ~ 4.096V&#xff0c;一般Vref要等于FSR 2、最大頻率&#xff1a;根據奈奎斯特采樣定理大于2倍的信號頻率才夠還原信號&#xff0c;所以選擇20/50倍更好&#xff0c; 3、最小精度&#xff0c;對于一給定模擬輸入&#xff0c;實際數字輸出與理論預…

基于深度學習的火災智能檢測系統設計與實現

在各類安全事故中&#xff0c;火災因其突發性強、破壞力大&#xff0c;一直是威脅人們生命財產安全的重大隱患。傳統的火災檢測方式多依賴煙霧傳感器、溫度傳感器等&#xff0c;存在響應滯后、易受環境干擾等問題。隨著深度學習技術的飛速發展&#xff0c;基于計算機視覺的火災…

HIVE實戰處理(二十四)留存用戶數

留存概念: 次X日活躍留存&#xff0c;次X日新增留存&#xff0c;也就是看今天的新增或活躍用戶在后續幾天的留存情況一、留存表的生成邏輯 因為用戶活躍日期和留存的日期無法對齊所以搞了2級分區&#xff08;dt,static_day&#xff09; 1&#xff09;首先獲得計算日D、根據要出…

W3C XHTML 活動:標準化的未來與交互式體驗

W3C XHTML 活動:標準化的未來與交互式體驗 概述 W3C(World Wide Web Consortium)是全球領先的互聯網技術標準制定組織。XHTML,作為W3C推薦的標準之一,是一種基于XML的標記語言,旨在提供一個更加結構化、兼容性和可擴展性更高的網頁內容表示方式。本文將圍繞W3C的XHTML活…

Java-數構鏈表

1.鏈表 1.1鏈表的概念和結構 鏈表是一種物理存儲結構上非連續存儲結構&#xff0c;數據元素的邏輯順序是通過鏈表中引用鏈接次序實現的。 這里大多討論無頭單向非循環鏈表。這種結構&#xff0c;結構簡單&#xff0c;一般與其他數據結構結合&#xff0c;作為其他數據結構的子…

Windows系統軟件游戲丟失找不到mgmtapi.dll修復解決方法

在使用電腦系統時經常會出現丟失找不到某些文件的情況&#xff0c;由于很多常用軟件都是采用 Microsoft Visual Studio 編寫的&#xff0c;所以這類軟件的運行需要依賴微軟Visual C運行庫&#xff0c;比如像 QQ、迅雷、Adobe 軟件等等&#xff0c;如果沒有安裝VC運行庫或者安裝…

初識C++——開啟新旅途

從今天開始主包也是掉入C這個深坑&#xff0c;上完課也是跟沒上一樣&#xff0c;所以寫好博客復習還是很重要的&#xff0c;話不多說&#xff0c;進入正題~~1、命名空間(1)namespace的價值與作用在C/C中&#xff0c;變量、函數和后面要學到的類都是大量存在的&#xff0c;這些變…

vue2 面試題及詳細答案150道(141 - 150)

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

第十三章 Go包管理

文章目錄使用logurs處理程序日志logrus 常用配置使用viper處理程序配置使用logurs處理程序日志 下載包&#xff0c;在終端執行命令 go get github.com/sirupsen/logrus官方示例 package mainimport (log "github.com/sirupsen/logrus" )func main() {log.WithFiel…