我在这里阅读了几个问题的答案,这些问题涉及java.time.LocalDateTime
和JSON属性之间的序列化和反序列化,但我似乎无法让它发挥作用。
我已经成功地将配置为以我希望的格式(YYY-MM-dd HH:mm
)返回日期,但在接受这种格式的JSON值时遇到了问题。
这些是我迄今所做的所有事情:
为jsr310
添加maven依赖项
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
在我的主类中指定的jsr310
:
@EntityScan(basePackageClasses = { App.class, Jsr310JpaConverters.class })
在application.properties
中禁用序列化为时间戳
spring.jackson.serialization.write_dates_as_timestamps=false
这是我对datetime的实体映射:
@Column(name = "start_date")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
@JsonFormat(pattern = "YYYY-MM-dd HH:mm")
private LocalDateTime startDate;
在我的数据库中,我以以下格式将此日期存储为时间戳:2016-12-01T23:00:00+00:00
。
如果我通过控制器访问这个实体,它将返回具有正确startDate格式的JSON。但是,当我尝试使用YYYY-MM-dd HH:mm
格式发布并反序列化它时,我会得到以下异常:
{
"timestamp": "2016-10-30T14:22:25.285+0000",
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "Could not read document: Can not deserialize value of type java.time.LocalDateTime from String \"2017-01-01 20:00\": Text '2017-01-01 20:00' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MonthOfYear=1, WeekBasedYear[WeekFields[SUNDAY,1]]=2017, DayOfMonth=1},ISO resolved to 20:00 of type java.time.format.Parsed\n at [Source: java.io.PushbackInputStream@679a734d; line: 6, column: 16] (through reference chain: com.gigsterous.api.model.Event[\"startDate\"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.time.LocalDateTime from String \"2017-01-01 20:00\": Text '2017-01-01 20:00' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MonthOfYear=1, WeekBasedYear[WeekFields[SUNDAY,1]]=2017, DayOfMonth=1},ISO resolved to 20:00 of type java.time.format.Parsed\n at [Source: java.io.PushbackInputStream@679a734d; line: 6, column: 16] (through reference chain: com.gigsterous.api.model.Event[\"startDate\"])",
"path": "/api/events"
}
我知道关于这个话题有很多答案,但是接下来的几个小时并不能帮助我找出我做错了什么,所以如果有人能告诉我我错过了什么,我会很高兴的。谢谢您对此的任何投入!
编辑:这些是过程中涉及的所有类:
储存库:
@Repository
public interface EventRepository extends PagingAndSortingRepository<Event, Long> {
}
主计长:
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Event> createEvent(@RequestBody Event event) {
return new ResponseEntity<>(eventRepo.save(event), HttpStatus.CREATED);
}
我的JSON请求payalod:
{
"name": "Test",
"startDate": "2017-01-01 20:00"
}
事件:
@Entity
@Table(name = "events")
@Getter
@Setter
public class Event {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "event_id")
private long id;
@Column(name = "name")
private String name;
@Column(name = "start_date")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
@JsonFormat(pattern = "YYYY-MM-dd HH:mm")
private LocalDateTime startDate;
}
发布于 2016-10-30 14:45:32
要传递的日期时间不是ISO本地日期时间格式。
变到
@Column(name = "start_date")
@DateTimeFormat(iso = DateTimeFormatter.ISO_LOCAL_DATE_TIME)
@JsonFormat(pattern = "YYYY-MM-dd HH:mm")
private LocalDateTime startDate;
并以“2011-12-03T10:15:30”格式传递日期字符串。
但是,如果您仍然希望传递自定义格式,则只需指定正确的格式化程序即可。
变到
@Column(name = "start_date")
@DateTimeFormat(iso = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
@JsonFormat(pattern = "YYYY-MM-dd HH:mm")
private LocalDateTime startDate;
我认为您的问题是@DateTimeFormat根本没有任何影响。因为Jackson正在进行反序列化,而且它对spring注释一无所知,我也没有看到spring在反序列化上下文中扫描这个注释。
或者,您可以尝试在注册Java时间模块时设置格式化程序。
LocalDateTimeDeserializer localDateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);
下面是工作良好的沙漠化器的测试用例。也许试着完全摆脱那个DateTimeFormat注释。
@RunWith(JUnit4.class)
public class JacksonLocalDateTimeTest {
private ObjectMapper objectMapper;
@Before
public void init() {
JavaTimeModule module = new JavaTimeModule();
LocalDateTimeDeserializer localDateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);
objectMapper = Jackson2ObjectMapperBuilder.json()
.modules(module)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.build();
}
@Test
public void test() throws IOException {
final String json = "{ \"date\": \"2016-11-08 12:00\" }";
final JsonType instance = objectMapper.readValue(json, JsonType.class);
assertEquals(LocalDateTime.parse("2016-11-08 12:00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm") ), instance.getDate());
}
}
class JsonType {
private LocalDateTime date;
public LocalDateTime getDate() {
return date;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
}
发布于 2016-11-07 23:21:34
你多年来用错了大小写:
@JsonFormat(pattern = "YYYY-MM-dd HH:mm")
应:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
随着这一变化,一切都如期而至。
发布于 2019-12-12 13:33:36
这对我起了作用:
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", shape = JsonFormat.Shape.STRING)
private LocalDateTime startDate;
https://stackoverflow.com/questions/40327970
复制相似问题