我正在项目中将 JSONObject 更改为 JsonNode。使用字符串或原始类型很容易做到。但是,当我尝试放置 pojo,尤其是它的 LocalDatetime 属性时,它不起作用。
public class JacksonTest {
private static final Logger log = LoggerFactory.getLogger(JacksonTest.class);
final ObjectMapper om = new ObjectMapper()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.registerModule(new JavaTimeModule());
@Test
void test() throws JsonProcessingException {
User user = new User(1L, "Alice", LocalDateTime.now());
log.info("user json is \n{}", om.writeValueAsString(user));
}
@Test
void test2() throws JsonProcessingException {
User user = new User(1L, "Alice", LocalDateTime.now());
log.info("user json is \n{}", new ObjectMapper()
.registerModule(new JavaTimeModule()).writeValueAsString(user));
}
@Test
void test3() throws JsonProcessingException {
User user = new User(1L, "Alice", LocalDateTime.now());
log.info("user json is \n{}", new ObjectMapper().writeValueAsString(user));
}
@Test
void test4() {
User user = new User(1L, "Alice", LocalDateTime.now());
log.info("user json is \n{}", om.createObjectNode()
.putPOJO("user", user).toPrettyString());
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class User {
Long id;
String username;
LocalDateTime lastLogin;
}
我写了一个测试类,但得到了不同的结果
test() 和 test2() 返回
{"id":1,"username":"Alice","lastLogin":"2023-11-28T09:25:06.7124585"}
,预期结果
test3() 抛出
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type 'java.time.LocalDateTime' not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.example.demo.test.User["lastLogin"])
,毫不奇怪
test() 返回一个 json 但包含一个异常,这真的让我很困惑
{
"user" : {
"id" : 1,
"username" : "Alice",
"lastLogin" : "[ERROR: (com.fasterxml.jackson.databind.exc.InvalidDefinitionException) Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module \"com.fasterxml.jackson.datatype:jackson-datatype-jsr310\" to enable handling (through reference chain: com.example.winter.demo.User[\"lastLogin\"])]"
}
}
方法 putPojo(String, Object) 似乎并不能始终如一地工作。在这种情况下,我必须使用替代方法 ObjectMapper#valueToTree(Object) 来代替。
谁能解释一下为什么会发生这种情况?
在
test3
您错过了注册JavaTimeModule()
:
@Test
public void test3() throws JsonProcessingException {
User user = new User(1L, "Alice", LocalDateTime.now());
log.info("user json is \n{}", new ObjectMapper()
.registerModule(new JavaTimeModule())
.writeValueAsString(user));
}
问题
test4
也许问题在于 putPOJO
方法如何处理 ObjectNode
中的 LocalDateTime 属性。
putPOJO
方法用于将 POJO 添加为 ObjectNode 中的字段,在您的情况下,它在序列化 LocalDateTime
属性时遇到困难。
要解决这个问题,可以使用 valueToTree
方法将 User 对象转换为 JsonNode
,然后将其添加到 ObjectNode
中:
@Test
public void test4() {
User user = new User(1L, "Alice", LocalDateTime.now());
ObjectNode objectNode = om.createObjectNode();
objectNode.set("user", om.valueToTree(user));
log.info("user json is \n{}", objectNode.toPrettyString());
}