Я работаю над проектом, в котором я интегрируюсь со сторонней службой, которая возвращает ответ JSON. Я использую Jackson для десериализации ответа в Java POJO. Ответ - это объект, который имеет несколько простых полей, которые Джексон может легко проанализировать. Однако ответ также содержит массив с одной записью, которая также является объектом. Когда Джексон пытается десериализовать его, я получаю объект верхнего уровня, содержащий список с единственной записью в списке, однако все поля для одной записи в списке равны нулю. Любая идея, что я делаю неправильно здесь?Jackson: Разбор объекта с массивом объектов
UPDATE: после установки FAIL_ON_UNKNOWN_PROPERTIES в true, я получаю следующую трассировку стека. Все еще не уверен, почему у него возникают проблемы с завернутым объектом «RecurringDetail» в массиве.
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Нераспознанное поле "RecurringDetail" (класс com.adyen.www.models.RecurringDetail), не помеченные как игнорируемые (19 известных свойств: "вариант", "contractTypes" , "tokenDetails", "aliasType", "name", "creationDate", "firstPspReference", "elv", "card", "дополнительные данные", "shopperName", "socialSecurityNumber", "billingAddress", "bank" recurringDetailReference "," paymentMethodVariant "," alias "," acquirer "," acquirerAccount "]) at [Источник: response.json; строка: 5, столбец: 33] (через цепочку ссылок: com.adyen.www.models.RecurringDetailsResult ["details"] -> java.util.ArrayList [0] -> com.adyen.www.models.RecurringDetail [" RecurringDetail "]) на com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from (UnrecognizedPropertyException.java:62) в com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty (DeserializationContext.java:834) на ком. fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty (StdDeserializer.java:1094) на com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty (BeanDeserializerBase.java:1470) на com.fasterxml.jackson. databind.deser.BeanDeserializerBase.handleUnknownVanilla (BeanDeserializerBase.java:1448) at com.fasterxml.jackson.databind.deser.BeanDeserializer .vanillaDeserialize (BeanDeserializer.java:282) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize (BeanDeserializer.java:140) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize (CollectionDeserializer .java: 287) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize (CollectionDeserializer.java:259) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize (CollectionDeserializer.java : 26) в com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize (SettableBeanProperty.java:499) на com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet (MethodProperty.java:101) в com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize (BeanDese rializer.java:276) на com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize (BeanDeserializer.java:140) на com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose (ObjectMapper.java:3798) на com.fasterxml.jackson.databind.ObjectMapper.readValue (ObjectMapper.Java: 2759)
JSON
{
"creationDate": "2017-01-26T23:11:20+01:00",
"details": [
{
"RecurringDetail": {
"acquirer": "TestPmmAcquirer",
"acquirerAccount": "TestPmmAcquirerAccount",
"additionalData": {
"cardBin": "440000"
},
"alias": "B133243153928547",
"aliasType": "Default",
"card": {
"expiryMonth": "8",
"expiryYear": "2018",
"holderName": "Steve HAll",
"number": "0008"
},
"contractTypes": [
"RECURRING"
],
"creationDate": "2017-01-26T23:11:20+01:00",
"firstPspReference": "8524854686798738",
"paymentMethodVariant": "visadebit",
"recurringDetailReference": "8414854686802111",
"variant": "visa"
}
}
],
"invalidOneclickContracts": "false",
"lastKnownShopperEmail": "[email protected]",
"shopperReference": "xggZcGauSSG5jP+akIlijQ=="
}
Unit Test
public class RecurringDetailResultTest {
public static ObjectMapper mapper = new ObjectMapper()
{
private static final long serialVersionUID = -174113593500315394L;
{
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
configure(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS, true);
setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
};
@Test
public void testParseRecurringDetailResulte() throws IOException {
RecurringDetailsResult result = mapper.readValue(new File("response.json"), new TypeReference<RecurringDetailsResult>(){});
if (result.getDetails() != null && !result.getDetails().isEmpty()) {
RecurringDetail detail = result.getDetails().get(0);
if (StringUtils.isEmpty(detail.getRecurringDetailReference())) {
fail("Recurring detail does not contain any information.");
}
} else {
fail("No result details returned.");
}
}
}
Модель (Root объекта)
public class RecurringDetailsResult
implements java.io.Serializable {
private static final long serialVersionUID = 5297684963950973136L;
private Date creationDate;
private String shopperReference;
private List<RecurringDetail> details;
private String lastKnownShopperEmail;
@JsonGetter("creationDate")
public Date getCreationDate () {
return this.creationDate;
}
@JsonSetter("creationDate")
public void setCreationDate (Date value) {
this.creationDate = value;
}
@JsonGetter("shopperReference")
public String getShopperReference () {
return this.shopperReference;
}
@JsonSetter("shopperReference")
public void setShopperReference (String value) {
this.shopperReference = value;
}
@JsonGetter("details")
public List<RecurringDetail> getDetails () {
return this.details;
}
@JsonSetter("details")
public void setDetails (List<RecurringDetail> value) {
this.details = value;
}
@JsonGetter("lastKnownShopperEmail")
public String getLastKnownShopperEmail () {
return this.lastKnownShopperEmail;
}
@JsonSetter("lastKnownShopperEmail")
public void setLastKnownShopperEmail (String value) {
this.lastKnownShopperEmail = value;
}
}
Модель (объект в массиве, все области этот парень имеет значение null, когда Джексон десериализует JSON)
public class RecurringDetail
implements java.io.Serializable {
private static final long serialVersionUID = 5302883242997268343L;
private String name;
private Date creationDate;
private Card card;
private ELV elv;
private Address billingAddress;
private String additionalData;
private Name shopperName;
private String socialSecurityNumber;
private String recurringDetailReference;
private BankAccount bank;
private String alias;
private String aliasType;
private TokenDetails tokenDetails;
private String variant;
private String paymentMethodVariant;
private String firstPspReference;
private List<String> contractTypes;
private String acquirer;
private String acquirerAccount;
@JsonGetter("name")
public String getName () {
return this.name;
}
@JsonSetter("name")
public void setName (String value) {
this.name = value;
}
@JsonGetter("creationDate")
public Date getCreationDate () {
return this.creationDate;
}
@JsonSetter("creationDate")
public void setCreationDate (Date value) {
this.creationDate = value;
}
@JsonGetter("card")
public Card getCard () {
return this.card;
}
@JsonSetter("card")
public void setCard (Card value) {
this.card = value;
}
@JsonGetter("elv")
public ELV getElv () {
return this.elv;
}
@JsonSetter("elv")
public void setElv (ELV value) {
this.elv = value;
}
@JsonGetter("billingAddress")
public Address getBillingAddress () {
return this.billingAddress;
}
@JsonSetter("billingAddress")
public void setBillingAddress (Address value) {
this.billingAddress = value;
}
@JsonGetter("additionalData")
public String getAdditionalData () {
return this.additionalData;
}
@JsonSetter("additionalData")
public void setAdditionalData (String value) {
this.additionalData = value;
}
@JsonGetter("shopperName")
public Name getShopperName () {
return this.shopperName;
}
@JsonSetter("shopperName")
public void setShopperName (Name value) {
this.shopperName = value;
}
@JsonGetter("socialSecurityNumber")
public String getSocialSecurityNumber () {
return this.socialSecurityNumber;
}
@JsonSetter("socialSecurityNumber")
public void setSocialSecurityNumber (String value) {
this.socialSecurityNumber = value;
}
@JsonGetter("recurringDetailReference")
public String getRecurringDetailReference () {
return this.recurringDetailReference;
}
@JsonSetter("recurringDetailReference")
public void setRecurringDetailReference (String value) {
this.recurringDetailReference = value;
}
@JsonGetter("bank")
public BankAccount getBank () {
return this.bank;
}
@JsonSetter("bank")
public void setBank (BankAccount value) {
this.bank = value;
}
@JsonGetter("alias")
public String getAlias () {
return this.alias;
}
@JsonSetter("alias")
public void setAlias (String value) {
this.alias = value;
}
@JsonGetter("aliasType")
public String getAliasType () {
return this.aliasType;
}
@JsonSetter("aliasType")
public void setAliasType (String value) {
this.aliasType = value;
}
@JsonGetter("tokenDetails")
public TokenDetails getTokenDetails () {
return this.tokenDetails;
}
@JsonSetter("tokenDetails")
public void setTokenDetails (TokenDetails value) {
this.tokenDetails = value;
}
@JsonGetter("variant")
public String getVariant () {
return this.variant;
}
@JsonSetter("variant")
public void setVariant (String value) {
this.variant = value;
}
@JsonGetter("paymentMethodVariant")
public String getPaymentMethodVariant () {
return this.paymentMethodVariant;
}
@JsonSetter("paymentMethodVariant")
public void setPaymentMethodVariant (String value) {
this.paymentMethodVariant = value;
}
@JsonGetter("firstPspReference")
public String getFirstPspReference () {
return this.firstPspReference;
}
@JsonSetter("firstPspReference")
public void setFirstPspReference (String value) {
this.firstPspReference = value;
}
@JsonGetter("contractTypes")
public List<String> getContractTypes () {
return this.contractTypes;
}
@JsonSetter("contractTypes")
public void setContractTypes (List<String> value) {
this.contractTypes = value;
}
@JsonGetter("acquirer")
public String getAcquirer () {
return this.acquirer;
}
@JsonSetter("acquirer")
public void setAcquirer (String value) {
this.acquirer = value;
}
@JsonGetter("acquirerAccount")
public String getAcquirerAccount () {
return this.acquirerAccount;
}
@JsonSetter("acquirerAccount")
public void setAcquirerAccount (String value) {
this.acquirerAccount = value;
}
}
Я пытался с этим UNWRAP_SINGLE_VALUE_ARRAYS установлен и истинным и ложным. Я также пробовал это с ACCEPT_SINGLE_VALUE_AS_ARRAY, установленным как true, так и false. – Steve
Я установил DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES в true и теперь получаю эту трассировку стека – Steve
Вы можете изменить json? проблема заключается в том, что ваш внешний объект не имеет корневого значения, а ваш внутренний объект. – teacurran