SpringBoot中@JsonFormat指定格式后ToDoDate字段无法解析日期
问题
开发SpringBoot Todo应用时,使用Postman提交JSON数据,toDoDate字段无法按@JsonFormat(pattern="dd/MM/yyyy")指定的格式解析,报错:
Cannot deserialize value of type
java.util.Datefrom String "09/07/2026": not a valid representation...
提交的JSON数据:
{"content":"Hello","status":"DONE","title":"Rppo","toDoDate":"09/07/2026"}
实体类ToDo中已为toDoDate字段添加@JsonFormat注解,相关代码如下:
ToDoController.java
package com.lcwd.todo.controllers; import com.lcwd.todo.models.ToDo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import com.lcwd.todo.services.ToDoService; import java.util.Date; import java.util.List; import java.util.Random; @RestController @RequestMapping("/todos") public class ToDoController { @Autowired private ToDoService toDoService; Logger logger= LoggerFactory.getLogger(ToDoController.class); Random random=new Random(); @PostMapping public ResponseEntity<ToDo> createToDoHandler(@RequestBody ToDo todo){ logger.info("created todo"); Date date=new Date(); todo.setAddedDate(date); int id= random.nextInt(9999); todo.setId(id); ToDo todo1=toDoService.createToDo(todo); return new ResponseEntity<>(todo1,HttpStatus.CREATED); } @GetMapping public ResponseEntity<List<ToDo>> getAllToDo(){ logger.info("Received all todos"); List<ToDo> todos=toDoService.getAllToDo(); return new ResponseEntity<>(todos,HttpStatus.OK); } @GetMapping("/{toDoId}") public ResponseEntity<ToDo> getSingleToDo(@PathVariable("toDoId") int id){ ToDo todo=toDoService.getSingleToDo(id); return new ResponseEntity<>(todo,HttpStatus.OK); } @PutMapping("/{todoId}") public String updateSingleToDo(@PathVariable("todoId") int id,@RequestBody ToDo todo){ String answer=toDoService.updateToDo(id,todo); return answer; } @DeleteMapping("/{toDoId}") public String getDeleteToDo(@PathVariable("toDoId") int id){ toDoService.deleteToDo(id); return "Deleted Successfully"; } }
ToDo.java
package com.lcwd.todo.models; import com.fasterxml.jackson.annotation.JsonFormat; import java.util.Date; public class ToDo { private String content; private String title; private String status; private int id; @JsonFormat(pattern="dd/MM/yyyy") private Date toDoDate; private Date addedDate; public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Date getToDoDate() { return toDoDate; } public void setToDoDate(Date toDoDate) { this.toDoDate = toDoDate; } public Date getAddedDate() { return addedDate; } public void setAddedDate(Date addedDate) { this.addedDate = addedDate; } public ToDo(String content, String title, String status, int id, Date toDoDate, Date addedDate) { this.content = content; this.title = title; this.status = status; this.id = id; this.toDoDate = toDoDate; this.addedDate = addedDate; } @Override public String toString() { return "ToDo{" + "content='" + content + '\'' + ", title='" + title + '\'' + ", status='" + status + '\'' + ", id=" + id + ", toDoDate=" + toDoDate + ", addedDate=" + addedDate + '}'; } }
ToDoService.java
package com.lcwd.todo.services; import com.lcwd.todo.models.ToDo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @Component public class ToDoService { ArrayList<ToDo> todos=new ArrayList<>(); Logger logger= LoggerFactory.getLogger(ToDoService.class); public ToDo createToDo(ToDo todo) { logger.info("Todos {}",this.todos); todos.add(todo); return todo; } public List<ToDo> getAllToDo() { return todos; } public ToDo getSingleToDo(int id){ ToDo toDo; for(ToDo todo1:todos){ if(todo1.getId()==id){ return todo1; } } return null; } public String updateToDo(int id,ToDo todo) { for(ToDo todo1:todos){ if(todo1.getId()==id){ todo1.setContent(todo.getContent()); todo1.setTitle(todo.getTitle()); todo1.setStatus(todo.getStatus()); } } return "updated successfully"; } public void deleteToDo(int id) { int index=0; for(ToDo todo:todos){ if(todo.getId()==id){ index=todos.indexOf(todo); todos.remove(index); } } } }
原因及解决方法
1. 缺少无参构造器
Jackson反序列化JSON到Java对象时,必须通过无参构造器实例化对象,再调用setter方法赋值。当前ToDo类仅定义了带参构造器,导致Jackson无法创建对象,进而无法解析日期字段。
修改ToDo.java,添加无参构造器:
public ToDo() { }
2. 补充@JsonFormat注解参数
仅指定pattern可能不够明确,建议补充shape和timezone参数,确保Jackson按字符串格式解析日期,同时避免时区差异问题:
@JsonFormat(pattern = "dd/MM/yyyy", shape = JsonFormat.Shape.STRING, timezone = "GMT+8") private Date toDoDate;
shape = JsonFormat.Shape.STRING:明确告知Jackson将该字段按字符串类型处理timezone:指定时区,避免因服务器时区不同导致解析异常
3. 确认Jackson依赖(可选)
Spring Boot的spring-boot-starter-web默认包含Jackson核心依赖(jackson-databind),如果项目中手动排除过该依赖,需要重新引入,否则无法完成JSON序列化/反序列化。
内容的提问来源于stack exchange,提问作者ssc1234
相关产品推荐
相关产品推荐

