我正在使用Jackson来解析JSON,其中一个字段是任意键和值的字典。如果我们只允许某些值类型(Map<String, Object>
,String
,Long
,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()
}
}
答案 0 :(得分:1)
好吧,找不到使用杰克逊提供的注释或类型系统表达我想要的方法,所以我最后通过编写自定义反序列化器来做我想避免的事情。
不可否认,这确实允许对允许的数据类型和解析错误进行更简洁的控制,但它比我想要的更冗长!
答案 1 :(得分: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
验证器(其中许多都建立在杰克逊身上)。