Spring Controller接收LocalDate表单提交JSON解析异常问题排查
我正在用Thymeleaf 3搭配Spring Boot 2开发,尝试提交一个包含日期字段的表单,但遇到了JSON解析错误。
我的Controller代码如下:
@PostMapping("template/new/samplings") @ResponseBody public SamplingsDto save(@RequestBody SamplingsDto samplings) { return samplingsService.save(samplings); }
SamplingsDto中的receptionDate和buildDate字段是LocalDate类型。我在JS里修改日期值为标准格式后提交,JS代码:
var receptionDate = $("#samplingsReceptionDatePicker").data('daterangepicker').startDate.format('YYYY-MM-DD'); var buildDate = $("#samplingsBuildDatePicker").data('daterangepicker').startDate.format('YYYY-MM-DD'); $("#samplingsForm").submit(function (e){ var data = $("#samplingsForm").serializeArray(); data.find(item => item.name === 'receptionDate').value = receptionDate; data.find(item => item.name === 'buildDate').value = buildDate; $.ajax({ type:"post", url: "/template/new/samplings", data: data, contentType: "application/json", success: function(data){ }, error: function (XMLHttpRequest, textStatus, errorThrown) { } }); });
提交后出现以下错误:
2018-05-19 14:03:49.824 WARN 12422 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'receptionDate': was expecting ('true', 'false' or 'null'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'receptionDate': was expecting ('true', 'false' or 'null') at [Source: (PushbackInputStream); line: 1, column: 15]
这个错误的核心原因是请求格式和你声明的contentType不匹配,加上Spring Boot处理LocalDate需要额外配置,我给你一步步解决:
1. 修正AJAX请求的数据格式
你把contentType设为了application/json,但serializeArray()返回的是键值对数组,jQuery会把它转成key=value&key2=value2这种表单编码格式的字符串,而不是JSON对象,后端Jackson解析JSON时自然就报错了。
修改JS代码,把表单数据转成JSON对象再序列化:
$("#samplingsForm").submit(function (e){ // 必须阻止表单默认提交行为,否则页面会刷新,AJAX请求可能被中断 e.preventDefault(); // 把表单数据转成普通JSON对象 const formData = {}; $("#samplingsForm").serializeArray().forEach(item => { formData[item.name] = item.value; }); // 替换日期字段为标准格式 formData.receptionDate = $("#samplingsReceptionDatePicker").data('daterangepicker').startDate.format('YYYY-MM-DD'); formData.buildDate = $("#samplingsBuildDatePicker").data('daterangepicker').startDate.format('YYYY-MM-DD'); $.ajax({ type: "post", url: "/template/new/samplings", data: JSON.stringify(formData), // 转成JSON字符串 contentType: "application/json", success: function(data){ console.log("保存成功", data); // 这里可以加成功后的操作,比如弹窗提示或跳转页面 }, error: function (XMLHttpRequest, textStatus, errorThrown) { console.error("保存失败", textStatus, errorThrown); } }); });
2. 配置Spring Boot支持LocalDate解析
Spring Boot默认的Jackson可能无法直接解析LocalDate类型,需要添加JSR310模块支持:
如果是Maven项目,在pom.xml中添加依赖:
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency>
或者在application.properties中配置Jackson的日期格式:
# 配置日期格式为YYYY-MM-DD spring.jackson.date-format=yyyy-MM-dd # 禁用时间戳格式,使用字符串格式 spring.jackson.serialization.write-dates-as-timestamps=false
3. 额外检查点
- 确保你的日期选择器返回的日期格式确实是
YYYY-MM-DD,和配置的格式一致; - 检查SamplingsDto中的字段名和表单input的
name属性完全一致(大小写敏感);
这样修改后,表单数据就能正确以JSON格式发送,后端也能正常解析LocalDate字段了。
内容的提问来源于stack exchange,提问作者robert trudel

