JSON-процессор Джексона перезаписывает свойства объекта при десериализации - PullRequest
0 голосов
/ 25 октября 2011

У меня интересная проблема. Джексон перезаписывает значения свойств «родительского» объекта значениями свойств «дочернего» объекта с тем же именем. Итак, чтобы быть более точным, это структура 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, что нормально, но не создает экземпляр Account для установки его на контакт - он записывает значения свойств учетной записи в свойства с такими же именами экземпляра Contact.

Я запутался и не уверен, с чего начать, как это исправить.

1 Ответ

1 голос
/ 14 ноября 2011

Я не могу воспроизвести любую проблему, аналогичную той, которая описана в исходном вопросе.

Следующий пример, созданный на основе описаний в исходном вопросе, работает должным образом, без ошибок или неправильной десериализации..

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_11@google.com"));
    account1.emails.add(new Email("email_12@google.com"));
    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_21@google.com"));
    account2.emails.add(new Email("email_22@google.com"));
    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_31@google.com"));
    contact.emails.add(new Email("email_32@google.com"));
    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_11@google.com"},{"email":"email_12@google.com"}],"phoneNumbers":[{"phone1":1111,"phone2":1112},{"phone1":1113,"phone2":1114}],"account":null}
    System.out.println(account2Json); // {"accountName":"account 2","emails":[{"email":"email_21@google.com"},{"email":"email_22@google.com"}],"phoneNumbers":[{"phone1":2221,"phone2":2222},{"phone1":2223,"phone2":2224}],"account":{"accountName":"account 1","emails":[{"email":"email_11@google.com"},{"email":"email_12@google.com"}],"phoneNumbers":[{"phone1":1111,"phone2":1112},{"phone1":1113,"phone2":1114}],"account":null}}
    System.out.println(contactJson); // {"name":"contact","emails":[{"email":"email_31@google.com"},{"email":"email_32@google.com"}],"phoneNumbers":[{"phone1":3331,"phone2":3332},{"phone1":3333,"phone2":3334}],"account":{"accountName":"account 2","emails":[{"email":"email_21@google.com"},{"email":"email_22@google.com"}],"phoneNumbers":[{"phone1":2221,"phone2":2222},{"phone1":2223,"phone2":2224}],"account":{"accountName":"account 1","emails":[{"email":"email_11@google.com"},{"email":"email_12@google.com"}],"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;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...