我有一个POJO类,如:
class Cat {
public Cat() {}
private String name;
private JsonElement arbitraryProperties;
}
我正在使用Jackson(JAXB),cat
是我要导入和导出的资源。
GET /cats/{id}
POST /cats
出口工作正常。导入无效,因为JsonElement
是抽象的。所以我将@JsonDeserialize(使用= MyJsonElementDeserialize.class)注释添加到arbitraryProperties field
。
MyJsonElementDeserialize
类看起来像:
public class JsonElementDeserialize extends JsonDeserializer<JsonElement> {
public JsonElementDeserialize() {
}
@Override
public JsonElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return new JsonObject(); // here I need to create my object later
}
}
当我现在用有效载荷调用POST / cats时:
{
"name": "Mia",
"arbitraryProperties": {
"a": 3,
"b": [],
"c": {
"d": "race"
}
}
}
Jacksons返回错误代码400:
无法识别的字段“a”(类Cat),未标记为可忽略(1个已知属性:“name”])。
我的错误在哪里?如何在我的POJO中有JsonElement
自动序列化和反序列化?
答案 0 :(得分:4)
这是一个简单的解决方案,使用Cat
中的setter方法将Jackson解析的内容(例如Map<String, Object>
)转换为GSON JsonElement
类型:
void setArbitraryProperties(Map<String, Object> properties) {
arbitraryProperties = new Gson().toJsonTree(properties).getAsJsonObject();
}
如果你不能在这里使用setter,你可以在自定义反序列化器中做类似的事情。我发现杰克逊的转换器更容易使用setter / getters。
请注意,Gson
实例用于将Map
转换为JsonElement
(实际为JsonObject
)。 toJsonTree的文档。
由于您在GSON中定义了一个类型的字段,因此您将GSON作为依赖项并且无情地需要GSON来创建此字段,您可以考虑Sharon的建议并跳过Jackson并使用GSON进行反序列化。
答案 1 :(得分:1)
这里的问题是反序列化器必须消耗它们所涵盖的所有内容:也就是说,如果你的反序列化器没有&#34;读取&#34;将绑定的JSON内容(此处为a
的内容),留待进一步处理。
解决方案应该很简单,只需调用
即可jsonParser.skipChildren();
在deserialize
方法中它将跳过当前输入标记及其所有内容(如果它的JSON对象或数组)。
或者,如果您想使用内容,可以使用
jsonParser.readValueAsTree();
还有其他一些便利方法。
答案 2 :(得分:1)
如果可以,我会将JsonElement更改为JsonNode,并使用Jackson的“Tree Model”。
答案 3 :(得分:0)
如果您使用的是Spring mvc,请尝试在控制器方法中使用“produce = MediaType.APPLICATION_JSON_VALUE”和@ResponseBody。