我正在尝试反序列化两种类型的json:
{
name: "bob",
worksAt: {
name: "Bobs department store",
location: "downtown"
},
age: 46
}
和
{
name: "Tom",
worksAt: "company:Bobs department store",
age: 27
}
进入这些对象:
第一种方法创建两个新对象,第二种方式根据字符串的内容从数据库中请求对象。
有点像杰克逊映射器如何将任意字符串反序列化为对象,对于像这样的对象:
public class Company{
public String name;
public Employee[] employees
public Company(){}
public Company(String json){
//turn string into object using whatever encoding you want blah blah blah...
}
}
问题是我需要两者。我需要它来处理对象和字符串。两者都可以从相同的输入到达。
我试过的第一个想法是制作转换器
它表示这些会创建一个委托类型以传递给反序列化器,但即使数据类型不是字符串,也始终应用转换器。所以这不起作用。
我也试过一个普通的反序列化器,但我找不到一种方法来推迟BeanDeserializer。 beanDeserializer非常复杂,我无法手动实例化它。我也看不到推迟使用jackson mapper中的默认反序列化器。
我是否必须重新实现jackson mappers反序列化才能执行此操作?解串器有没有办法说“我不能这样做,使用默认实现。”?
编辑:进一步的进展。基于Jackson Mapper源代码,看起来你可以像这样实例化bean反序列化器:
DeserializationConfig config = ctxt.getConfig();
JavaType type = config.constructType(_valueClass);
BeanDescription introspect = config.introspect(type);
JsonDeserializer<Object> beanDeserializer = ctxt.getFactory().createBeanDeserializer(ctxt, type , introspect);
但由于某种原因,所有_beanProperties都为其_valueDeserializer设置了FailingDeserializer,整个过程失败了。所以我不知道为什么会这样......
答案 0 :(得分:2)
你试过writing a custom deserializer吗?这使您可以最大程度地控制杰克逊如何反序列化对象。您可以尝试单向反序列化,如果出现错误,请尝试其他方式。
杰克逊也可以处理polymorphic deserialization,虽然这需要对json进行少量更改以包含类型信息,听起来你的问题限制可能不允许这样做。
答案 1 :(得分:1)
如果我正确理解了问题,我建议使用JsonNode。您可以在顶级类型中定义一个setter,如下所示:
setWorksAt(JsonNode node) {
if (node.getNodeType == JsonNodeType.STRING) {
String name = node.getText();
name = name.substring(name.lastIndexOf(':'));
this.company = new Company(name);
} else if (node.getNodeType == JsonNodeType.OBJECT) {
this.company = mapper.treeToValue(node, Company.class);
}
}
这允许您处理两个单独的worksFor输入,同时仍允许标准映射器处理OBJECT案例的任何子结构。
答案 2 :(得分:0)
最新版本的Jackson(我认为2.8+,绝对可以使用2.9)你可以使用多个@JsonCreator并执行以下操作:
public class Company {
private String name;
private String location;
private Company(String name, String location) {
this.name = name;
this.location = location;
}
private Company(String stringRepresentation) {
// add code here to parse string and extract name and location
}
@JsonCreator
private static Company fromJson(
@JsonProperty("name") String name,
@JsonProperty("location") String location)
{
return new Company(name, location);
}
@JsonCreator
private static Company fromJson(String str) {
return Company(str);
}
}