Java 使用Jackson解析JSON时限制映射值

Java 使用Jackson解析JSON时限制映射值,java,json,jackson,Java,Json,Jackson,我使用解析JSON,其中一个字段是任意键和值的字典。如果不是因为我们只允许某些值类型(String,Long,Double,Long[],Long[]和Double[]),这通常会直接映射到Java映射 目前,我们完整地解析文档,然后迭代每个映射的每个值,并执行instanceof检查它是否有效,当无效时向用户返回一个错误。当然,对于长文档来说,这是相当低效的,我们有很多这样的文档 有没有人知道如何将这个映射值类型限制表达给Jackson,以便在解析过程中捕获输入中的任何错误?@JsonSubT

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

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

有没有人知道如何将这个映射值类型限制表达给Jackson,以便在解析过程中捕获输入中的任何错误?
@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()
    }
}
静态类文档{
清单项目;
}
静态类项{
/*…其他领域被切断*/
公共地图有效载荷;
@杰索尼奥雷
public void check()引发异常{
for(对象值:item.payload.values()){
如果(字符串的值实例){
else if(value instanceof Long){}
else if(长[]的值instanceof{}
else if(value instanceof Double){}
else if(值instanceof Double[]){}
else{抛出新异常(“不支持的值类型”);}
}
}
}
无效读取(InputStream)引发异常{
ObjectMapper mapper=新的ObjectMapper();
Doc Doc=mapper.readValue(流,Doc.class);
//检查所有有效负载类型是否有效
用于(项目:单据项目){
项目.检查()
}
}

好吧,我无法用Jackson提供的注释或类型系统来表达我想要的内容,所以我最终做了我试图避免的事情,而是编写了一个自定义反序列化程序


无可否认,这确实允许对允许的数据类型和解析错误进行更简洁的控制,但它比我希望的要详细得多!

没有具体的功能可以做到这一点,但是创建对不可接受的子类型抛出异常的
映射
子类怎么样

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
  }
} 
public class LimitedMap扩展了HashMap{
公共对象put(字符串键、对象值){
//验证它不是布尔值或映射。请注意,Jackson使用的是列表
//对于JSON数组,Double表示浮点(默认情况下),Integer或Long表示int
}
} 

另一种选择是使用
JSON模式
validator(其中许多是基于Jackson构建的)。

请编写解析
JSON
的源类。