Jackson用泛型反序列化JSON

时间:2018-07-05 10:11:50

标签: java json jackson

我与Jackson进行反序列化有一些问题(是多态的吗?)。

假设我具有以下JSON结构

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

其中list可能包含不同类型的数据。我已经使用泛型使用以下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]
}

如何为类型T指定反序列化器?我已经研究了多态反序列化,但是我认为它不能解决我的问题。

我还可以创建扩展LocalDateResponseList的特定GeneralResponseList<LocalDate>。如何为特定响应指定反序列化器?

您能为我提供解决方案或提示来解决此问题吗?

1 个答案:

答案 0 :(得分:2)

假设您有一个类似的课程:

public class GeneralResponseList<T> {

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

    // Getters and setters
}

您可以使用TypeReference<T>

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

如果您有多种日期格式(如注释中所述),则可以编写自定义反序列化器来处理:

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");
    }
}

然后将解串器添加到模块中,并在Module实例中注册ObjectMapper

ObjectMapper mapper = new ObjectMapper();

SimpleModule module = new SimpleModule();
module.addDeserializer(LocalDate.class, new LocalDateDeserializer());
mapper.registerModule(module);
相关问题