Jackson JSON 处理器在反序列化期间覆盖对象的属性

发布于 2024-12-11 12:00:21 字数 611 浏览 0 评论 0原文

我有一个有趣的问题。 Jackson 用具有相同名称的“子”对象的属性值覆盖“父”对象的属性值。因此,更准确地说,这是我拥有的 Java 结构。

public class Contact {
    ...
    String name;
    List<Email> emails;
    List<PhoneNumbers> phoneNumbers;
    Account account;
    ...
}

public class Account {
    ...
    String accountName;
    List<Email> emails;
    List<PhoneNumbers> phoneNumbers;
    Account account;
    ...
}

因此,当我形成 Contact JSON 对象并将其发送到服务器时,一切都会正常,直到 BeanDeserializer 考虑 Contact 类的属性。然后,它开始读取 JSON 的帐户部分的属性,这是可以的,但不会创建帐户实例来将其设置为联系人 - 它将帐户属性的值写入与联系人实例名称相同的属性中。

我很困惑,不知道从哪里开始寻找如何解决这个问题。

I have interesting problem. Jackson overwrites values of properties on the 'parent' object with values of properties of 'child' object that have same name. So, to be more precise, this is Java structure I have

public class Contact {
    ...
    String name;
    List<Email> emails;
    List<PhoneNumbers> phoneNumbers;
    Account account;
    ...
}

public class Account {
    ...
    String accountName;
    List<Email> emails;
    List<PhoneNumbers> phoneNumbers;
    Account account;
    ...
}

So, when I form Contact JSON object and send it to server, everything goes fine until BeanDeserializer comes into account property of Contact class. Then, it starts reading proeprties of account part of JSON, which is ok, but does not create Account instance to set it on contact - it writes values of account's properties into properties with same names of Contact instance.

I am confused and not sure where to start looking how to fix this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乖不如嘢 2024-12-18 12:00:21

我无法重现与原始问题中描述的类似的任何问题。

以下示例是根据原始问题中的描述创建的,按预期工作,没有错误或不正确的反序列化。

import java.util.LinkedList;
import java.util.List;

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.ObjectMapper;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    Account account1 = new Account();
    account1.accountName = "account 1";
    account1.emails = new LinkedList<Email>();
    account1.emails.add(new Email("[email protected]"));
    account1.emails.add(new Email("[email protected]"));
    account1.phoneNumbers = new LinkedList<PhoneNumbers>();
    account1.phoneNumbers.add(new PhoneNumbers(1111, 1112));
    account1.phoneNumbers.add(new PhoneNumbers(1113, 1114));

    Account account2 = new Account();
    account2.accountName = "account 2";
    account2.emails = new LinkedList<Email>();
    account2.emails.add(new Email("[email protected]"));
    account2.emails.add(new Email("[email protected]"));
    account2.phoneNumbers = new LinkedList<PhoneNumbers>();
    account2.phoneNumbers.add(new PhoneNumbers(2221, 2222));
    account2.phoneNumbers.add(new PhoneNumbers(2223, 2224));
    account2.account = account1;

    Contact contact = new Contact();
    contact.name = "contact";
    contact.emails = new LinkedList<Email>();
    contact.emails.add(new Email("[email protected]"));
    contact.emails.add(new Email("[email protected]"));
    contact.phoneNumbers = new LinkedList<PhoneNumbers>();
    contact.phoneNumbers.add(new PhoneNumbers(3331, 3332));
    contact.phoneNumbers.add(new PhoneNumbers(3333, 3334));
    contact.account = account2;

    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibilityChecker(  
        mapper.getVisibilityChecker()  
          .withFieldVisibility(Visibility.ANY));

    String account1Json = mapper.writeValueAsString(account1);
    String account2Json = mapper.writeValueAsString(account2);
    String contactJson = mapper.writeValueAsString(contact);

    System.out.println(account1Json); // {"accountName":"account 1","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":1111,"phone2":1112},{"phone1":1113,"phone2":1114}],"account":null}
    System.out.println(account2Json); // {"accountName":"account 2","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":2221,"phone2":2222},{"phone1":2223,"phone2":2224}],"account":{"accountName":"account 1","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":1111,"phone2":1112},{"phone1":1113,"phone2":1114}],"account":null}}
    System.out.println(contactJson); // {"name":"contact","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":3331,"phone2":3332},{"phone1":3333,"phone2":3334}],"account":{"accountName":"account 2","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":2221,"phone2":2222},{"phone1":2223,"phone2":2224}],"account":{"accountName":"account 1","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":1111,"phone2":1112},{"phone1":1113,"phone2":1114}],"account":null}}}

    Account account1Copy = mapper.readValue(account1Json, Account.class);
    Account account2Copy = mapper.readValue(account2Json, Account.class);
    Contact contactCopy = mapper.readValue(contactJson, Contact.class);

    System.out.println(account1.equals(account1Copy)); // true
    System.out.println(account2.equals(account2Copy)); // true
    System.out.println(contact.equals(contactCopy)); // true
  }
}

class Contact
{
  String name;
  List<Email> emails;
  List<PhoneNumbers> phoneNumbers;
  Account account;

  @Override
  public boolean equals(Object o)
  {
    Contact c = (Contact) o;
    if (name.equals(c.name))
      if (emails.containsAll(c.emails))
        if (c.emails.containsAll(emails))
          if (phoneNumbers.containsAll(c.phoneNumbers))
            if (c.phoneNumbers.containsAll(phoneNumbers))
              return account.equals(c.account);
    return false;
  }
}

class Account
{
  String accountName;
  List<Email> emails;
  List<PhoneNumbers> phoneNumbers;
  Account account;

  @Override
  public boolean equals(Object o)
  {
    Account a = (Account) o;
    if (accountName.equals(a.accountName))
      if (emails.containsAll(a.emails))
        if (a.emails.containsAll(emails))
          if (phoneNumbers.containsAll(a.phoneNumbers))
            if (a.phoneNumbers.containsAll(phoneNumbers))
              if (account != null && a.account != null)
                return account.equals(a.account);
              else if (account == null && a.account == null)
                return true;
    return false;
  }
}

class Email
{
  String email;

  @JsonCreator
  Email(@JsonProperty("email") String e) {email = e;}

  @Override
  public boolean equals(Object o)
  {
    Email e = (Email) o;
    return email.equals(e.email);
  }
}

class PhoneNumbers
{
  long phone1;
  long phone2;

  @JsonCreator
  PhoneNumbers(@JsonProperty("phone1") long p1, @JsonProperty("phone2")long p2) {phone1 = p1; phone2 = p2;}

  @Override
  public boolean equals(Object o)
  {
    PhoneNumbers p = (PhoneNumbers) o;
    return phone1 == p.phone1 && phone2 == p.phone2;
  }
}

I'm not able to reproduce any problem similar to what's described in the original question.

The following example, created based on the descriptions in the original question, works as expected, without errors or improper deserialization.

import java.util.LinkedList;
import java.util.List;

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.ObjectMapper;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    Account account1 = new Account();
    account1.accountName = "account 1";
    account1.emails = new LinkedList<Email>();
    account1.emails.add(new Email("[email protected]"));
    account1.emails.add(new Email("[email protected]"));
    account1.phoneNumbers = new LinkedList<PhoneNumbers>();
    account1.phoneNumbers.add(new PhoneNumbers(1111, 1112));
    account1.phoneNumbers.add(new PhoneNumbers(1113, 1114));

    Account account2 = new Account();
    account2.accountName = "account 2";
    account2.emails = new LinkedList<Email>();
    account2.emails.add(new Email("[email protected]"));
    account2.emails.add(new Email("[email protected]"));
    account2.phoneNumbers = new LinkedList<PhoneNumbers>();
    account2.phoneNumbers.add(new PhoneNumbers(2221, 2222));
    account2.phoneNumbers.add(new PhoneNumbers(2223, 2224));
    account2.account = account1;

    Contact contact = new Contact();
    contact.name = "contact";
    contact.emails = new LinkedList<Email>();
    contact.emails.add(new Email("[email protected]"));
    contact.emails.add(new Email("[email protected]"));
    contact.phoneNumbers = new LinkedList<PhoneNumbers>();
    contact.phoneNumbers.add(new PhoneNumbers(3331, 3332));
    contact.phoneNumbers.add(new PhoneNumbers(3333, 3334));
    contact.account = account2;

    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibilityChecker(  
        mapper.getVisibilityChecker()  
          .withFieldVisibility(Visibility.ANY));

    String account1Json = mapper.writeValueAsString(account1);
    String account2Json = mapper.writeValueAsString(account2);
    String contactJson = mapper.writeValueAsString(contact);

    System.out.println(account1Json); // {"accountName":"account 1","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":1111,"phone2":1112},{"phone1":1113,"phone2":1114}],"account":null}
    System.out.println(account2Json); // {"accountName":"account 2","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":2221,"phone2":2222},{"phone1":2223,"phone2":2224}],"account":{"accountName":"account 1","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":1111,"phone2":1112},{"phone1":1113,"phone2":1114}],"account":null}}
    System.out.println(contactJson); // {"name":"contact","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":3331,"phone2":3332},{"phone1":3333,"phone2":3334}],"account":{"accountName":"account 2","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":2221,"phone2":2222},{"phone1":2223,"phone2":2224}],"account":{"accountName":"account 1","emails":[{"email":"[email protected]"},{"email":"[email protected]"}],"phoneNumbers":[{"phone1":1111,"phone2":1112},{"phone1":1113,"phone2":1114}],"account":null}}}

    Account account1Copy = mapper.readValue(account1Json, Account.class);
    Account account2Copy = mapper.readValue(account2Json, Account.class);
    Contact contactCopy = mapper.readValue(contactJson, Contact.class);

    System.out.println(account1.equals(account1Copy)); // true
    System.out.println(account2.equals(account2Copy)); // true
    System.out.println(contact.equals(contactCopy)); // true
  }
}

class Contact
{
  String name;
  List<Email> emails;
  List<PhoneNumbers> phoneNumbers;
  Account account;

  @Override
  public boolean equals(Object o)
  {
    Contact c = (Contact) o;
    if (name.equals(c.name))
      if (emails.containsAll(c.emails))
        if (c.emails.containsAll(emails))
          if (phoneNumbers.containsAll(c.phoneNumbers))
            if (c.phoneNumbers.containsAll(phoneNumbers))
              return account.equals(c.account);
    return false;
  }
}

class Account
{
  String accountName;
  List<Email> emails;
  List<PhoneNumbers> phoneNumbers;
  Account account;

  @Override
  public boolean equals(Object o)
  {
    Account a = (Account) o;
    if (accountName.equals(a.accountName))
      if (emails.containsAll(a.emails))
        if (a.emails.containsAll(emails))
          if (phoneNumbers.containsAll(a.phoneNumbers))
            if (a.phoneNumbers.containsAll(phoneNumbers))
              if (account != null && a.account != null)
                return account.equals(a.account);
              else if (account == null && a.account == null)
                return true;
    return false;
  }
}

class Email
{
  String email;

  @JsonCreator
  Email(@JsonProperty("email") String e) {email = e;}

  @Override
  public boolean equals(Object o)
  {
    Email e = (Email) o;
    return email.equals(e.email);
  }
}

class PhoneNumbers
{
  long phone1;
  long phone2;

  @JsonCreator
  PhoneNumbers(@JsonProperty("phone1") long p1, @JsonProperty("phone2")long p2) {phone1 = p1; phone2 = p2;}

  @Override
  public boolean equals(Object o)
  {
    PhoneNumbers p = (PhoneNumbers) o;
    return phone1 == p.phone1 && phone2 == p.phone2;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文