1

我正在使用Jackson解析 JSON,其中一个字段是任意键和值的字典。Map<String, Object>如果不是因为我们只允许某些值类型(StringLong、和)Double,这通常会直接映射到 Java 。Long[]Double[]

目前我们完整解析文档,然后遍历每个映射的每个值并执行instanceof检查它是否有效,当无效时向用户返回错误。对于我们有很多长文档,这当然是相当低效的。

有没有人知道一种向杰克逊表达这种映射值类型限制的方法,以便在解析期间可以捕获输入中的任何错误?@JsonSubTypes注释看起来可能是相关的,但无法确定在这种情况下如何应用它。

这是我希望替换的代码类型的示例:

static class Doc {
    List<Item> items;
}

static class Item {
    /* ...other fields snipped... */
    public Map<String, Object> payload;

    @JsonIgnore
    public void check() throws Exception {
        for(Object value: item.payload.values()) {
            if(value instanceof String) { 
            else if(value instanceof Long) { }
            else if(value instanceof Long[]) { }
            else if(value instanceof Double) { }
            else if(value instanceof Double[]) { }
            else { throw new Exception("Unsupported value type"); }
        }
    }
}

void read(InputStream stream) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    Doc doc = mapper.readValue(stream, Doc.class);

    // Check all payload types are valid
    for(Item item: doc.items) {
        item.check()
    }
}
4

2 回答 2

1

没有特定的功能可以做到这一点,但是如何创建Map为不可接受的子类型抛出异常的子类呢?就像是:

public class LimitedMap extends HashMap<String,Object> {
  public Object put(String key, Object value) {
     // verify it's not a Boolean or Map. And note that Jackson uses List
     // for JSON Arrays; Double for floating point (by default), Integer or Long for ints
  }
} 

另一种方法是使用JSON Schema验证器(其中许多基于杰克逊)。

于 2012-11-19T18:05:37.803 回答
1

好吧,找不到一种方法来使用 Jackson 提供的注释或类型系统来表达我想要的东西,所以我最终通过编写自定义反序列化器来做我试图避免的事情。

诚然,这确实允许对允许的数据类型和解析错误进行更简洁的控制,但它比我想要的更冗长!

于 2012-11-18T11:29:26.427 回答