Jackson JsonNode putPojo 不适用于 LocalDatetime

问题描述 投票:0回答:1

我正在项目中将 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;
}

我写了一个测试类,但得到了不同的结果

  1. test() 和 test2() 返回

    {"id":1,"username":"Alice","lastLogin":"2023-11-28T09:25:06.7124585"}
    ,预期结果

  2. 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"])
    ,毫不奇怪

  3. 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) 来代替。

谁能解释一下为什么会发生这种情况?

java json jackson
1个回答
0
投票

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());
}
© www.soinside.com 2019 - 2024. All rights reserved.