【问题标题】:Parsing JSON to POJO with LocalDateTime using Jackson "Unexpected token (START_OBJECT), expected VALUE_STRING: Expected array or string."使用杰克逊“意外的令牌(START_OBJECT),预期的VALUE_STRING:预期的数组或字符串”将JSON解析为带有LocalDateTime的POJO。
【发布时间】:2017-05-27 19:52:34
【问题描述】:

我在这里阅读了许多关于将 JSON 解析为 Java 对象的帖子,并且在我介绍 LocalDateTime 之前,我的解析工作正常。我尝试使用 Java 8 解析器、JSR310 模块并构建自定义 - 下面描述了每个方面的障碍。任何帮助将不胜感激!

这是我的 JSON 字符串,由 Jackson 从另一个 POJO 创建:

{"validEscortsWTheirSpecReqs":"MAYBE",
 "modifiedDateTimeNeedToBeThere":     
    {"dayOfMonth":6,"dayOfWeek":"MONDAY","month":"FEBRUARY","year":2017,
     "hour":10,"minute":1,"second":24,"nano":0,"dayOfYear":37,"monthValue":2,
     "chronology":{"id":"ISO","calendarType":"iso8601"}
    }
}

生成

com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected VALUE_STRING: Expected array or string. at 
...
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
    at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:1376)
    at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:118)
    at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:39)
...

调用自:

ComputeArrive response = mapper.readValue(responseString, ComputeArrive.class);

响应具有以下字段:

Logger logger // 不应该被 JSON 映射,没有 getter/setter 静态最终长序列版本UID = 1L; // " String validEscortsWTheirSpecReqs = "YES" // 想要映射 LocalDateTime modifiedDateTimeNeedToBeThere // 想要映射

我现在可能已经注册了太多的模块,添加它们来尝试让它解析:

    mapper.findAndRegisterModules();
    //mapper           .registerModule(new ParameterNamesModule());
    mapper.registerModule(new Jdk8Module());
    mapper.registerModule(new JavaTimeModule());
    mapper.registerModule(new JSR310Module());

所以我尝试将 Spring Boot 依赖项添加到我的项目中,并为 JSR310 编写一个定制器(考虑到上面的模块,这似乎是不必要的):

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
        return objectMapper;
    }
}

我的应用程序有许多依赖项,所以我不想将任何东西作为它的“父级”,并添加了以下依赖项。但是,没有找到“Jackson2ObjectMapperBuilder”类,因此上面的代码无法使用这些依赖项进行编译:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>aopalliance</groupId>
    <artifactId>aopalliance</artifactId>
    <version>1.0</version>
</dependency>   

我没有找到很多关于“Jackson2ObjectMapperBuilderCustomizer”的文档,这可能是“Jackson2ObjectMapperBuilder”的替代品——这可能是问题所在。请注意,上面的类不是我实例化的,因为我假设 Spring 实例化了它。

任何关于如何解析我的回复的想法将不胜感激!

【问题讨论】:

  • 我也有这个确切的问题(除了手动而不是通过 Spring)。你解决了吗??
  • 这个 -> ""modifiedDateTimeNeedToBeThere": {"dayOfMonth":6,"dayOfWeek":"MONDAY","month":"FEBRUARY","year":2017, "hour":10 ,"分":1,"秒":24,"纳米":0,"dayOfYear":37,"monthValue":2, "年表":{"id":"ISO","calendarType":"iso8601 “}”将很难被杰克逊反序列化。你似乎走在正确的轨道上。您是否尝试过反序列化更合适的内容,例如 iso 日期。我遇到了类似的问题,这篇文章帮助了我:lewandowski.io/2016/02/…

标签: java json spring parsing


【解决方案1】:

对我来说,这个问题是通过将JavaTimeModule 添加到Jackson2ObjectMapperBuilder 来解决的,如下所示:

@Configuration
public class MyConfiguration {

    @Bean
    @Primary
    public Jackson2ObjectMapperBuilder objectMapperBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        return builder.modulesToInstall(new JavaTimeModule());
    }

}

然后 Spring 将这个映射器与注册的模块一起使用。

【讨论】:

    【解决方案2】:

    我认为问题在于LocalDate的解析,试试这个:

    {
        "validEscortsWTheirSpecReqs":"MAYBE",
        "modifiedDateTimeNeedToBeThere":[6,2,2017]
    }
    

    用整数表示的日、月、年。

    【讨论】:

      【解决方案3】:

      正如@Tobias 所说,使用JavaTimeModule 将解决问题。

      在您的 pom xml 中添加 JSR310 依赖项以允许 Jackson 能够识别 Java 8 Date&Time API 数据类型:

      <dependency>
          <groupId>com.fasterxml.jackson.datatype</groupId>
          <artifactId>jackson-datatype-jsr310</artifactId>
      </dependency>
      

      您现在可以像这样在 Jackson 配置中使用 JavaTimeModule

      @Configuration
      public class JacksonConfig {
      
          @Bean
          @Primary
          public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
              ObjectMapper objectMapper = builder.createXmlMapper(false).build();
              objectMapper.registerModule(new JavaTimeModule());
              objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
              objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
              return objectMapper;
          }
      }
      

      您应该使用此配置来序列化和反序列化 LocalDate 或其他 Java 8 Date&Time API 数据类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-24
        • 2020-10-16
        • 1970-01-01
        • 2021-10-17
        • 1970-01-01
        • 2021-03-28
        • 1970-01-01
        • 2022-08-23
        相关资源
        最近更新 更多