【问题标题】:Jackson Json ObjectMapper fails to map nested ZonedDateTime instance when converting custom types for DynamoDB via custom converter当通过自定义转换器为 DynamoDB 转换自定义类型时,Jackson Json ObjectMapper 无法映射嵌套的 ZonedDateTime 实例
【发布时间】:2017-05-18 19:37:58
【问题描述】:

我有一件物品想存放在 Dynamo 中:

public class Statement {
@DynamoDBTypeConverted(converter = ListLineItemConverter.class)
private List<LineItem> items;
}

LineItem的定义如下:

public class LineItem {
private ZonedDateTime dateStart;
private ZonedDateTime dateEnd;
private long balance;

@DynamoDBTypeConverted(converter = ZonedDateTimeConverter.class)
public getDateStart() {...}

@DynamoDBTypeConverted(converter = ZonedDateTimeConverter.class)
public getDateEnd() {...} 
}

我一直在使用已知的 ZonedDateTime 转换器,如下所示:

public class ZonedDateTimeConverter implements DynamoDBTypeConverter<String, ZonedDateTime> {
    public ZonedDateTimeConverter(){}

    @Override
    public String convert(final ZonedDateTime time) {
        return time.toString();
    }

    @Override
    public ZonedDateTime unconvert(final String stringValue) {
        return ZonedDateTime.parse(stringValue);
    }
}

当它在基类上注释时,转换器可以完美地工作。但是我有一个嵌套在项目列表中的自定义类型,我似乎无法弄清楚如何让 DynamoDB 正确转换/取消转换嵌套的 ZonedDateTime。

我什至没有运气为 LineItem 列表编写了一个自定义转换器:

public class ListLineItemConverter implements DynamoDBTypeConverter<String, List<LineItem>> {

    private ObjectMapper objectMapper;

    public ListLineItemConverter() {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // THIS LINE OF CODE FIXED THE ISSUE FOR ME
        objectMapper.findAndRegisterModules();
        // THIS LINE OF CODE FIXED THE ISSUE FOR ME
    }

    @Override
    public String convert(List<LineItem> object) {
        try {
            String result = objectMapper.writeValueAsString(object);
            return objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("bad json marshalling");
        }
    }

    @Override
    public List<LineItem> unconvert(String object) {
        try {
            return objectMapper.readValue(object, new TypeReference<List<LineItem>>() {});
        } catch (IOException e) {
            throw new RuntimeException("bad json unmarshalling");
        }
    }
}

我似乎无法使用任何注释组合来使其工作。我总是得到:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.time.ZonedDateTime: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)

编辑:如果我从LineItem 中注释掉ZonedDateTime 的实例,那么代码完全可以正常工作。因此,当 @DynamoDBTypeConverted 被深埋 3 层时,DynamoDB 无法读取它:

Statement.items.get[0].dateStart // annotations aren't working at this level

Statement.items.get[0].dateEnd // annotations aren't working at this level

【问题讨论】:

    标签: java spring amazon-web-services amazon-dynamodb objectmapper


    【解决方案1】:

    在 ZonedDateTime 的嵌套实例上使用 Jackson 解析器时似乎出现了问题,并且它不会自动拾取它。

    我已切换到较新版本的 Jackson,甚至包含 JSR310 模块,以确保支持与编组/解组较新的 java 8 时间构造的兼容性,但可惜。

    奇怪的是,一行代码为我修复了它:

    objectMapper.findAndRegisterModules();

    取自:https://stackoverflow.com/a/37499348/584947

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多