在阅读JSON文件时,我想按照以下方式映射我的课程:
public class Effect {
private final String type;
private final Map<String, String> parameters;
public Effect(String type, Map<String, String> parameters) {
this.type = type;
this.parameters = parameters;
}
public String getType() {
return this.type;
}
public Map<String, String> getParameters() {
return this.parameters;
}
}
{
"type": {
"key1": "value1",
"key2": "value2",
}
}
因此,映射的JSON对象包含type
作为唯一键,parameters
作为其值。
我想在构造函数上使用@JsonCreator
,但无法弄清楚如何映射字段。我是否需要编写自定义反序列化器,或者是否有更简单的方法来映射我想要的类?
我写了一个自定义反序列化器,它可以实现我想要的功能,但可能有一种更简单的方法,可能只有注释,我想知道:
public class EffectDeserializer extends StdDeserializer<Effect> {
private static final long serialVersionUID = 1L;
public EffectDeserializer() {
super(Effect.class);
}
@Override
public Effect deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
JsonNode node = parser.getCodec().readTree(parser);
Iterator<String> fieldNames = node.fieldNames();
if(fieldNames.hasNext()) {
String type = fieldNames.next();
Map<String, String> parameters = new HashMap<>();
for(Iterator<Entry<String, JsonNode>> fields = node.get(type).fields(); fields.hasNext(); ) {
Entry<String, JsonNode> field = fields.next();
parameters.put(field.getKey(), field.getValue().textValue());
}
return new Effect(type, parameters);
}
return null;
}
}
我发现的另一种方法是添加JsonCreator
(本例中为构造函数),它使用Map.Entry<String, Map<String, String>
并使用它来初始化值,如下所示:
@JsonCreator
public Effect(Map.Entry<String, Map<String, String>> entry) {
this.type = entry.getKey();
this.parameters = entry.getValue();
}
如果没有办法用“普通”构造函数完成它,我可能会最终使用它,因为它使用Jackson的Map.Entry
默认映射,减少了可能的误差范围。
答案 0 :(得分:1)
添加一个静态工厂方法,该方法接受带有动态密钥的Map
:
@JsonCreator
public static Effect create(Map<String, Map<String, String>> map) {
String type = map.keySet().iterator().next();
return new Effect(type, map.get(type));
}
编辑:刚刚注意到这基本上是使用Map.Entry
的自己解决方案的丑陋版本。我会改用它。