简体   繁体   English

Jackson用泛型反序列化JSON

[英]Jackson to deserialize JSON with generics

I've some issues with polymorphic (is it polymorphic?) deserialising with Jackson. 我对Jackson的多态性(是多态性)反序列化有一些问题。

Suppose I have the following JSON structure 假设我具有以下JSON结构

{
  "list": [
    "02/01/2018",
    "03/01/2018",
    "04/01/2018",
    "05/01/2018",
    "08/01/2018",
    "05/02/2018"
  ]
}

where list may contains different types of data. 其中list可能包含不同类型的数据。 I've modelled the data structure with the following POJO, using generics. 我已使用泛型使用以下POJO对数据结构进行了建模。

public class GeneralResponseList<T> extends BaseResponse {

    @JsonProperty("list")
    private List<T> list;

    @JsonProperty("paging")
    private Paging paging;

    @JsonProperty("sorting")
    private List<Sorting> sorting;

    // [CUT]
}

How to specify the deserializer for type T ? 如何为T类型指定反序列化器? I've looked at polymorphic deserialization but I think it doesn't solve my issue. 我看过多态反序列化,但是我认为这不能解决我的问题。

I can also create a specific LocalDateResponseList which extends GeneralResponseList<LocalDate> . 我还可以创建扩展GeneralResponseList<LocalDate>的特定LocalDateResponseList How to specify the deserializer for the the specific response? 如何为特定响应指定反序列化器?

Can you suggest me a solution or hints to solve this issue. 您能给我建议解决方案还是提示解决此问题。

Assuming that you have a class like: 假设您有一个类似的课程:

public class GeneralResponseList<T> {

    @JsonProperty("list")
    private List<T> list;

    // Getters and setters
}

You can use TypeReference<T> : 您可以使用TypeReference<T>

GeneralResponseList<LocalDate> response = 
    mapper.readValue(json, new TypeReference<GeneralResponseList<LocalDate>>() {});

If you have multiple date formats, as you mentioned in the comments, you can write a custom deserializer to handle that: 如注释中所述,如果您有多种日期格式,则可以编写一个自定义反序列化器来处理:

public class LocalDateDeserializer extends StdDeserializer<LocalDate> {

    private List<DateTimeFormatter> availableFormatters = new ArrayList<>();

    protected LocalDateDeserializer() {
        super(LocalDate.class);
        availableFormatters.add(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        availableFormatters.add(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    @Override
    public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) 
            throws IOException {

        String value = p.getText();

        if (value == null) {
            return null;
        }

        for (DateTimeFormatter formatter : availableFormatters) {
            try {
                return LocalDate.parse(value, formatter);
            } catch (DateTimeParseException e) {
                // Safe to ignore
            }
        }

        throw ctxt.weirdStringException(value, LocalDate.class, "Unknown date format");
    }
}

Then add the deserializer to a module and register the Module in the ObjectMapper instance: 然后将反序列化器添加到模块中,然后在ObjectMapper实例中注册该Module

ObjectMapper mapper = new ObjectMapper();

SimpleModule module = new SimpleModule();
module.addDeserializer(LocalDate.class, new LocalDateDeserializer());
mapper.registerModule(module);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM