我有一个有趣的问题。 Jackson使用具有相同名称的“child”对象的属性值覆盖“父”对象上的属性值。所以,更确切地说,这是我有的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的帐户部分的proeprties,这是好的,但是没有创建Account实例来设置联系 - 它将帐户属性的值写入具有相同名称的Contact实例的属性。
我很困惑,不知道从哪里开始寻找解决方法。
答案 0 :(得分:1)
我无法重现任何类似于原始问题中描述的问题。
以下示例基于原始问题中的描述创建,按预期工作,没有错误或不正确的反序列化。
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;
}
}