問題
在Postman里可成功執行的POST請求:
找到Postman的Code
因為cURL基本上算是行業標準,所以Postman默認選中cURL,支持切換不同的開發語言:
點擊上圖右上角的復制按鈕,得到cURL腳本。
Windows 11家庭版,打開Git Bash客戶端,版本為:
git version 2.47.1.windows.1
執行上述cURL腳本異常:
報錯信息:
{"code":400,"msg":"JSON parse error: Invalid UTF-8 start byte 0xb4; nested exception is com.fasterxml.jackson.core.JsonParseException: Invalid UTF-8 start byte 0xb4\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 3, column: 18]"}
分析
根據上面幾行簡短的報錯信息,提取幾個關鍵內容:
code=400
:表明這是客戶端異常,此處的客戶端是Git Bash;- JsonParseException和StreamUtils:表明服務端確實有接收到客戶端提交的請求,要不然客戶端也無法得知Jackson框架里的類JsonParseException,當然也無法得知Spring框架里的StreamUtils工具類;
- 報錯原因是非法JSON:
JSON parse error
; - 編碼異常:
Invalid UTF-8 start byte 0xb4
。
分析起來,看起來頭頭是道,怎么解決問題呢?
排查
遇到問題時,還是習慣性將問題拋給ChatGPT,結果這次是真的全程被ChatGPT的胡言亂語給糊弄,浪費不少時間。
一一嘗試:
- 很明確是小寫雙引號,不是大寫雙引號;
- 將上述cURL腳本使用txt文件保存,并保存為不帶BOM的格式,沒有解決問題;
- 報錯提示是第三行
line: 3, column: 18
,好像是min_score
字段,去掉引號試試,還是報錯:
--data-binary
還是報錯:
方法一
反復嘗試+試錯,浪費不少時間,ChatGPT終于給出一個可行的解決方案:
也就是在Git Bash執行的目錄下,新增一個payload.json
文件,內容就是POST請求的requestBody:
{"retriever_type": "TEXT","question": "大模型技術如何幫助數據中心實現高效減碳?","min_score": "0.2","max_results": "10"
}
然后將命令:
--data '{"retriever_type": "TEXT","question": "大模型技術如何幫助數據中心實現高效減碳?","min_score": "0.2","max_results": "10"
}'
修改為(其他部分不變):--data @payload.json
執行效果:
方法二
為了執行一個在Postman可以成功執行的cURL腳本,我需要另存為一個JSON文件,感覺非常反人類。于是繼續追問ChatGPT,給出一個不使用文件的方法:
printf '%s' '{"retriever_type": "TEXT","question": "大模型技術如何幫助數據中心實現高效減碳?","min_score": "0.2","max_results": "10"
}' | curl --location 'http://api.test.tesla.com/rag_online/rag/retrieval' \--header 'tesla-token: 1111222233334444' \--header 'Content-Type: application/json' \--data @-
和上面的解決方法非常類似。
GET
Git Bash客戶端下執行cURL GET命令沒有問題,只是在執行POST命令才有問題。
CMD/PowerShell
既然Git Bash客戶端不能用,于是將注意力放在其他客戶端。
打開cmd或PowerShell,粘帖cURL腳本,結果給我提示:您將粘貼包含多行的文本。如果將此文本粘貼到 shell 中,則可能會導致命令意外執行。是否繼續?
如上圖所示,CMD和PowerShell無法識別多行cURL腳本,會拆分成多行,當然會執行失敗。
怎么解決?
ChatGPT又讓我失望
并不能解決問題。
Google找到一篇類似的報錯Jackson JSON parser invalid utf-8 start byte。
TODO:未解決。
Mac
上述cURL腳本在同事的Mac開發機上(使用的終端未知),可執行成功。
解決方案
Git Bash
如果是GET請求,直接可使用Git Bash。但是對于POST請求,如果堅持要使用Git Bash客戶端,有兩種方法:
- 使用文件
curl --location 'http://api.test.tesla.com/rag_online/rag/retrieval' \
--header 'tesla-token: 1111222233334444' \
--header 'Content-Type: application/json' \
--data @payload.json
- 使用管道符
printf '%s' '{"retriever_type": "TEXT","question": "大模型技術如何幫助數據中心實現高效減碳?","min_score": "0.2","max_results": "10"
}' | curl --location 'http://api.test.tesla.com/rag_online/rag/retrieval' \--header 'ecmas-token: 1111222233334444' \--header 'Content-Type: application/json' \--data @-
Mac
Mac比Windows強,受開發者青睞,不是沒有原因的。
WSL
Windows 8不知道什么時候開始支持WSL,另外貌似有不少問題,Windows 10/11好像也不是一開始就支持WSL的。
總而言之,如果可以的話,建議升級Windows版本,安裝WSL,比CMD、PowerShell功能強大:
使用WSL可執行多行cURL腳本。當然,WSL是一個Ubuntu系統,默認自帶cURL命令。
關于WSL,參考我寫的另一篇Windows 10/11安裝使用WSL。
參考
- ChatGPT