Spring RestController HTTP 400错误调试:JSON转PrinterData失败求助
遇到这种超长JSON解析出错的问题确实挺闹心的,我给你分享几个实战过的调试方案,应该能帮你快速定位问题:
1. 自定义全局异常捕获,直接返回解析错误详情
Spring返回400是因为Jackson解析JSON失败时抛出了HttpMessageNotReadableException,我们可以写一个全局异常处理器,把Jackson的具体错误信息(比如行号、列号、错误字段)返回给客户端,不用看服务器日志也能知道问题在哪:
@RestControllerAdvice public class JsonParseExceptionHandler { @ExceptionHandler(HttpMessageNotReadableException.class) public ResponseEntity<String> handleJsonParseFailure(HttpMessageNotReadableException ex) { StringBuilder errorMsg = new StringBuilder("JSON解析失败: "); // 层层剥开异常,拿到Jackson的具体错误 Throwable rootCause = ex.getRootCause(); if (rootCause instanceof JsonMappingException) { JsonMappingException jsonEx = (JsonMappingException) rootCause; errorMsg.append(String.format("行号: %d, 列号: %d, 错误描述: %s", jsonEx.getLineNumber(), jsonEx.getColumnNumber(), jsonEx.getOriginalMessage())); } else if (rootCause instanceof JsonParseException) { JsonParseException jsonEx = (JsonParseException) rootCause; errorMsg.append(String.format("行号: %d, 列号: %d, 语法错误: %s", jsonEx.getLineNumber(), jsonEx.getColumnNumber(), jsonEx.getMessage())); } else { errorMsg.append(ex.getMessage()); } return new ResponseEntity<>(errorMsg.toString(), HttpStatus.BAD_REQUEST); } }
这样下次再收到错误请求,客户端就能直接拿到具体的错误位置,不用瞎猜了。
2. 单独开启Jackson的调试日志
如果你暂时没法查看完整的Spring日志,可以在配置文件里单独打开Jackson的日志输出,让它打印解析错误的细节:
如果是application.properties:
logging.level.com.fasterxml.jackson.databind=DEBUG logging.level.com.fasterxml.jackson.core=DEBUG
如果是application.yml:
logging: level: com.fasterxml.jackson.databind: DEBUG com.fasterxml.jackson.core: DEBUG
这样Jackson会把解析时的每一步细节(包括出错的JSON片段)打印出来,能帮你快速定位问题。
3. 本地手动解析测试JSON
把出问题的JSON抓下来(可以在异常处理器里把请求体保存到本地文件,或者让客户端重新发一次并抓包),然后写个简单的测试类,用Spring用的同一个ObjectMapper来手动解析,这样能在本地调试:
@SpringBootTest public class JsonParsingTest { @Autowired private ObjectMapper objectMapper; // 用Spring容器里的ObjectMapper,和业务代码保持一致 @Test public void testProblematicJson() throws IOException { // 读取本地的错误JSON文件 String badJson = Files.readString(Paths.get("path/to/your/bad.json")); try { PrinterData data = objectMapper.readValue(badJson, PrinterData.class); } catch (JsonProcessingException e) { e.printStackTrace(); // 这里会打印详细的错误信息,包括行号和字段 // 还可以在这里加断点,查看异常的详细堆栈和上下文 } } }
本地调试时,你可以给readValue方法加断点,一步步跟踪Jackson的解析过程,看具体是哪个字段或者语法导致的错误。
4. 调整异常断点的类型
你之前加的Java异常断点没生效,大概率是选的异常类型不对。应该直接针对Jackson的具体异常来加断点:
- 在Eclipse里打开
Breakpoints视图,点击Add Java Exception Breakpoint - 输入
com.fasterxml.jackson.databind.JsonMappingException(字段映射错误,比如类型不匹配)和com.fasterxml.jackson.core.JsonParseException(JSON语法错误) - 勾选
Caught和Uncaught,这样当Jackson抛出这些异常时,程序会自动暂停,你可以查看栈信息和错误详情,甚至能看到正在解析的JSON内容。
5. 先用工具快速校验JSON语法
对于超长JSON,手动查语法太费劲,可以用本地的JSON校验工具(比如IntelliJ/Eclipse的JSON插件,或者离线的JSON校验工具)先快速扫一遍,看看有没有基础的语法错误,比如缺失引号、逗号不匹配、括号没闭合等,排除掉低级错误后再查字段映射问题。
内容的提问来源于stack exchange,提问作者JavaSheriff

