当前位置: 首页 > 知识库问答 >
问题:

为Jackson Mapper提供多种反序列化同一对象的方法

苍阳成
2023-03-14

我正在尝试反序列化两种类型的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...
    }
}

问题是我两者都需要。我需要它来处理对象和字符串。两者都可以从同一个输入到达。

我尝试的第一个想法是制造一个转换器

它说这些创建一个委托类型来传递给反序列化器,但是即使数据类型不是字符串,转换器也总是被应用。所以这不起作用。

我也尝试过一个普通的反序列化器,但是我找不到一种方法来服从豆反序列化器。豆反序列化器太复杂了,我无法手动实例化它。我也看不出有什么方法可以服从杰克逊映射器中的默认反序列化器。

我是否必须重新实现杰克逊映射器反序列化才能执行此操作?反序列化程序有没有办法说“我不能这样做,使用默认实现。

编辑:一些进一步的进展。根据 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,整个过程都失败了。所以我不知道为什么会这样...

共有3个答案

聂鹏云
2023-03-14

使用最新版本的 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);
    }
}
丌官哲彦
2023-03-14

如果我正确理解这个问题,我建议使用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);
    }
}

这允许您处理输入的两个单独的工作,同时仍然允许标准映射器处理OBJECT案例的任何子结构。

丁正阳
2023-03-14

您是否尝试过编写自定义反序列化程序?这使您可以最大程度地控制Jackson如何反序列化对象。您可以尝试以一种方式反序列化,如果出现错误,请尝试另一种方式。

Jackson还可以处理多态反序列化,尽管这需要对json进行小的更改以包含类型信息,听起来您的问题约束可能不允许这样做。

 类似资料:
  • 本文向大家介绍PHP多种序列化/反序列化的方法详解,包括了PHP多种序列化/反序列化的方法详解的使用技巧和注意事项,需要的朋友参考一下 摘要:序列化是将变量转换为可保存或传输的字符串的过程;反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性.. 序列化是将变量转换为可保存或传输的字符串的过程;反序列化就是在适当的时候把这个字符

  • 我已经将Spring Boot应用程序配置为以我希望的格式()返回日期,但是在JSON中接受这种格式的值有问题。 这些都是我到目前为止所做的事情: 为添加了maven依赖项: 在我的数据库中,我以以下格式将此日期存储为时间戳:。 如果我通过我的控制器访问这个实体,它将返回具有正确startDate格式的JSON。但是,当我尝试使用格式发布并反序列化它时,我会遇到以下异常: 我知道有很多关于这个话题

  • 我的RESTendpoint返回包含对象字段的响应对象。序列化一切正常,但当我开始为此API编写客户端时,我遇到了反序列化问题。我根据一些关于使用Jackson进行多态序列化的问题/文章制作了这个示例代码。它演示了这个问题。 我的期望(以及我对列表的期望 我现在拥有的Object: 但我需要反序列化除动物列表之外的其他类型的对象。救命啊!

  • 问题内容: 你好亲爱的同事们, 我有一个Garden类,在其中我可以序列化和反序列化多个Plant类对象。如果想将其分配给mein静态方法中的调用变量,则可以进行序列化,但是不能进行反序列化。 反序列化代码: 我的调用代码: 编辑 我有一个空的Pointer异常 @NilsH的解决方案工作正常,谢谢! 问题答案: 如何序列化整个列表呢?无需序列化列表中的每个对象。 如果那不能解决您的问题,请发布有

  • 问题内容: 我已经在SO中阅读了一些关于答案的问题,这些问题与JSON属性之间的序列化和反序列化有关,但我似乎无法使其正常工作。 我已经设法将Spring Boot应用程序配置为以所需的格式()返回日期,但在以JSON格式接收值时遇到问题。 这些是我到目前为止所做的所有事情: 增加了对Maven的依赖: 在我的主要课程中指定: 禁用序列化作为时间戳记: 这是我的日期时间实体映射: 在我的数据库中,

  • 序列化对象时,我设置, 将对象附加到序列化文件。例如,我将电子邮件对象序列化到同一个文件中。 当反序列化这些保存的对象时,我想得到所有对象,但它只给出第一个对象。 我发现了一个类似的问题,反序列化java中的许多对象?但是没有,方法。那么,反序列化时如何获取所有对象?