SpringBoot排查和解決JSON解析錯(cuò)誤(400 Bad Request)的方法
問(wèn)題背景
1. 問(wèn)題描述
開(kāi)發(fā)者在調(diào)用本地Spring Boot接口時(shí),遇到400 Bad Request錯(cuò)誤:
curl --location 'http://localhost:8089/after/spider' \ --header 'Content-Type: application/json' \ --data '{ "channelId": 100000132, "platformAccount": "yien", "platformPwd": "123456", "enName": "jinYiMu", "grabDays": 15, "aesPwd": "example" }'
返回錯(cuò)誤:
{ "timestamp": "2025-06-12T03:04:50.459+00:00", "status": 400, "error": "Bad Request", "message": "JSON parse error: Unexpected character (' ' (code 160)): was expecting double-quote to start field name", "path": "/after/spider" }
2. 錯(cuò)誤分析
錯(cuò)誤信息表明:
- JSON解析失敗,原因是存在非法字符
' ' (code 160)
(即HTML的空格
)。 - 根本問(wèn)題:JSON請(qǐng)求體中混入了不可見(jiàn)的特殊字符,導(dǎo)致Jackson解析失敗。
解決方案
1. 手動(dòng)重新輸入JSON
問(wèn)題原因:JSON可能是從網(wǎng)頁(yè)、Word文檔或富文本編輯器復(fù)制的,導(dǎo)致包含隱藏字符。
解決方法:手動(dòng)重新輸入JSON,避免復(fù)制粘貼:
{ "channelId": 100000132, "platformAccount": "yien", "platformPwd": "123456", "enName": "jinYiMu", "grabDays": 15, "aesPwd": "example" }
2. 使用工具清理JSON
推薦工具:
- VS Code(安裝JSON格式化插件)
- Notepad++(顯示所有字符)
- 在線JSON校驗(yàn)工具(如 JSONLint)
示例:
// 格式化前(可能含隱藏字符) { "channelId": 100000132 } // 格式化后(標(biāo)準(zhǔn)JSON) { "channelId": 100000132 }
3. 檢查請(qǐng)求原始數(shù)據(jù)
使用 hexdump
或 xxd
查看請(qǐng)求體中的隱藏字符:
echo '{ "channelId": 100000132 }' | hexdump -C
輸出示例:
00000000 7b 0a c2 a0 22 63 68 61 6e 6e 65 6c 49 64 22 3a |{..."channelId":|
其中 c2 a0
是
的UTF-8編碼,說(shuō)明存在非法字符。
4. 代碼層面過(guò)濾非法字符
如果問(wèn)題持續(xù),可以在Java后端對(duì)輸入進(jìn)行清理:
import org.springframework.util.StringUtils; public class SpiderParam { private String enName; // 移除所有空白字符 public void setEnName(String enName) { this.enName = enName.replaceAll("\\u00A0", ""); // 移除 } }
深入排查:Spring Boot的JSON解析機(jī)制
1. Jackson庫(kù)的工作流程
Spring Boot默認(rèn)使用 Jackson 解析JSON,流程如下:
- 客戶(hù)端發(fā)送JSON請(qǐng)求。
- DispatcherServlet 接收請(qǐng)求,交給 HttpMessageConverter 處理。
- MappingJackson2HttpMessageConverter 使用 ObjectMapper 解析JSON。
- 如果解析失敗,拋出 JsonParseException,返回400錯(cuò)誤。
2. 關(guān)鍵日志配置
在 application.yml
中啟用詳細(xì)日志:
logging: level: org.springframework.web: DEBUG org.springframework.validation: DEBUG server: error: include-binding-errors: always include-message: always
日志會(huì)顯示具體的解析錯(cuò)誤,例如:
JSON parse error: Unexpected character (' ' (code 160))
3. 使用 @Valid 進(jìn)行參數(shù)校驗(yàn)
在Controller中添加 @Valid
注解,捕獲校驗(yàn)錯(cuò)誤:
@PostMapping("/spider") public ResponseEntity<String> spider(@Valid @RequestBody SpiderParam spiderParam) { return ResponseEntity.ok("Success"); }
全局異常處理:
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<String> handleValidationException(MethodArgumentNotValidException ex) { String errorMsg = ex.getBindingResult().getFieldErrors().stream() .map(error -> error.getField() + ": " + error.getDefaultMessage()) .collect(Collectors.joining(", ")); return ResponseEntity.badRequest().body(errorMsg); } }
錯(cuò)誤示例:
channelId: must not be null, platformAccount: must not be blank
最佳實(shí)踐
1. 如何避免JSON解析錯(cuò)誤?
問(wèn)題 | 解決方案 |
---|---|
非法空白字符 | 手動(dòng)輸入JSON,或用工具清理 |
字段名不匹配 | 使用 @JsonProperty("en_name") |
缺少必填字段 | 添加 @NotNull 注解 |
類(lèi)型不匹配 | 確保JSON和Java類(lèi)型一致 |
2. 推薦工具
工具 | 用途 |
---|---|
Postman | 測(cè)試API,生成標(biāo)準(zhǔn)JSON |
VS Code | 格式化JSON,顯示隱藏字符 |
curl | 快速測(cè)試請(qǐng)求 |
總結(jié)
本文通過(guò)一個(gè)實(shí)際案例,詳細(xì)分析了Spring Boot中JSON解析錯(cuò)誤的排查方法:
- 問(wèn)題定位:日志分析 + 錯(cuò)誤信息解讀。
- 解決方案:手動(dòng)輸入JSON、工具清理、代碼過(guò)濾。
- 深入機(jī)制:Jackson解析流程 + 參數(shù)校驗(yàn)。
- 最佳實(shí)踐:避免非法字符、使用校驗(yàn)注解。
關(guān)鍵點(diǎn):
- 始終手動(dòng)輸入JSON,避免復(fù)制粘貼。
- 啟用詳細(xì)日志,快速定位問(wèn)題。
- 使用
@Valid
進(jìn)行校驗(yàn),提高代碼健壯性。
到此這篇關(guān)于SpringBoot排查和解決JSON解析錯(cuò)誤(400 Bad Request)的方法的文章就介紹到這了,更多相關(guān)SpringBoot JSON解析錯(cuò)誤內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Cloud Admin健康檢查 郵件、釘釘群通知的實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud Admin健康檢查 郵件、釘釘群通知的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08IDEA中java: 找不到符號(hào) 符號(hào): 變量log
這篇文章主要介紹了使用@Slf4j注解時(shí)出現(xiàn)log變量找不到符號(hào)問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-06-06Eureka源碼閱讀之環(huán)境搭建及工程結(jié)構(gòu)
這篇文章主要為大家介紹了Eureka源碼閱讀之環(huán)境搭建的工程結(jié)構(gòu)及調(diào)試需知詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-10-10詳解Java中布隆過(guò)濾器(Bloom Filter)原理及其使用場(chǎng)景
布隆過(guò)濾器是1970年由布隆提出的,它實(shí)際上是一個(gè)很長(zhǎng)的二進(jìn)制向量和一系列隨機(jī)映射函數(shù),它的作用是檢索一個(gè)元素是否存在我們的集合之中,本文給大家詳細(xì)的講解一下布隆過(guò)濾器,感興趣的同學(xué)可以參考閱讀2023-05-05關(guān)于logBack配置日志文件及編碼配置的問(wèn)題
這篇文章主要介紹了logBack配置日志文件及編碼配置的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Json字符串與Object、List、Map的互轉(zhuǎn)工具類(lèi)
今天小編就為大家分享一篇關(guān)于Json字符串與Object、List、Map的互轉(zhuǎn)工具類(lèi),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12java讀取resources文件詳解及實(shí)現(xiàn)代碼
這篇文章主要介紹了java讀取resources文件詳解及實(shí)現(xiàn)代碼的相關(guān)資料,在開(kāi)發(fā)項(xiàng)目的時(shí)候經(jīng)常會(huì)遇到讀取文件夾里面的內(nèi)容,需要的朋友可以參考下2017-07-07Mybatis返回單個(gè)實(shí)體或者返回List的實(shí)現(xiàn)
這篇文章主要介紹了Mybatis返回單個(gè)實(shí)體或者返回List的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Spring sentinel哨兵模式相關(guān)原理解析
這篇文章主要介紹了Spring sentinel哨兵模式相關(guān)原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11