【问题标题】:Unable to deserialize Object Array via Jackson Yaml无法通过 Jackson Yaml 反序列化对象数组
【发布时间】:2024-01-21 02:20:02
【问题描述】:

我正在尝试反序列化将特定操作(枚举)映射到参数(String[])的 YAML 配置文件。为了有一个 YAML 的起点,我首先用 Java 构建了对象结构,然后将其序列化。

读回该输出并对其进行反序列化也会导致下面的异常,这是出乎意料的,因为那是直接从马嘴里说出来的。

我的 Java 结构:

@NoArgsConstructor
@AllArgsConstructor
@ToString(doNotUseGetters = true)
@Data
public class Session {
  @EqualsAndHashCode.Exclude protected List<ActionInstance> actions;
}

@NoArgsConstructor
@AllArgsConstructor
@ToString(doNotUseGetters = true)
@Data
public class ActionInstance {
  protected Action action;
  protected String[] arguments;
}

public enum Action {
  Left,
  Right,
  Up,
  Down;
}

YAML(直接取自 Jackson 的序列化输出,读回会导致以下异常):

actions: !<java.util.ImmutableCollections$List12>
- !<java.util.ImmutableCollections$List12>
  arguments:
  - 90.00
  action: Left

Jackson 服务反序列化:

objectMapper.readValue(inputStream, Session.class)

例外:

com.fasterxml.jackson.databind.exc.MismatchedInputException
Unexpected token (VALUE_STRING), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class Action

编辑#1:

final Session export = new Session();
        export.setActions(
            List.of(
                new ActionInstance(Action.Left, new String[] {"90.00"})));
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        serializationService.serialize(export, baos);

我的 Jackson 实现大致是这样的:

outputStream.write(objectMapper.writeValueAsBytes(data));

ObjectMapperProvider:

public class ObjectMapperProvider implements Provider<ObjectMapper> {
  protected final ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
  protected final JavaTimeModule javaTimeModule = new JavaTimeModule();

  @Inject
  public ObjectMapperProvider() {
    // Hack time module to allow 'Z' at the end of string (i.e. javascript json's)
    javaTimeModule.addDeserializer(
        LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));
    objectMapper.registerModule(javaTimeModule);
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

    objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator());

【问题讨论】:

  • 在第二行中,!&lt;java.util.ImmutableCollections$List12&gt; 是错误的,因为需要一个 ActionInstance 对象。更重要的是,Jackson 是一个高级抽象,因此永远不应该生成 YAML 标签(因为这不是 JSON 功能)所以问题就出现了你正在做什么来获得这个输出。请显示生成此 YAML 输出的代码。

标签: java jackson yaml


【解决方案1】:

解决方法很简单:

动作:!

  • 参数:
    • 90.00 动作:!

【讨论】: