首页 > 解决方案 > 无法从 Pojo 类反序列化 JSON 响应和访问类

问题描述

我正在创建 pojo 类来反序列化 Rest Assured 中的 JSON 响应。我还在反序列化过程中利用了 Lombok 注释。

这是一个 JSON 响应,是我测试的重点。它有多个嵌套列表,就像我将要测试的许多其他响应一样。

{
    "annualReturnFilingMonth": null,
    "financialReportFilingMonth": null,
    "nzsxCode": null,
    "annualReturnLastFiled": "2002-05-29T12:15:56.000+1200",
    "hasConstitutionFiled": true,
    "countryOfOrigin": "NZ",
    "overseasCompany": "No",
    "extensiveShareholding": false,
    "stockExchangeListed": null,
    "shareholding": {
        "numberOfShares": 300,
        "shareAllocation": [
            {
                "allocation": 100,
                "shareholder": [
                    {
                        "type": "individual",
                        "appointmentDate": "2001-09-17T00:00:00.000+1200",
                        "vacationDate": null,
                        "individualShareholder": {
                            "firstName": "Paul",
                            "middleNames": "James",
                            "lastName": "DILLON",
                            "fullName": "DILLON, Paul James"
                        },
                        "otherShareholder": null,
                        "shareholderAddress": {
                            "uniqueIdentifier": "13254258",
                            "startDate": "2001-09-17T00:00:00.000+1200",
                            "endDate": null,
                            "careOf": null,
                            "address1": "44b Mexico Grove",
                            "address2": "India",
                            "address3": "Wellington",
                            "address4": null,
                            "postCode": null,
                            "countryCode": null,
                            "addressType": null,
                            "pafId": null
                        }
                    }
                ]
            },
            {
                "allocation": 100,
                "shareholder": [
                    {
                        "type": "individual",
                        "appointmentDate": "2001-09-17T00:00:00.000+1200",
                        "vacationDate": null,
                        "individualShareholder": {
                            "firstName": "John",
                            "middleNames": null,
                            "lastName": "MATRIX",
                            "fullName": "MATRIX, John"
                        },
                        "otherShareholder": null,
                        "shareholderAddress": {
                            "uniqueIdentifier": "13254259",
                            "startDate": "2001-09-17T00:00:00.000+1200",
                            "endDate": null,
                            "careOf": null,
                            "address1": "351 France Grove",
                            "address2": "Warner Village",
                            "address3": "Wellington",
                            "address4": null,
                            "postCode": null,
                            "countryCode": null,
                            "addressType": null,
                            "pafId": null
                        }
                    }
                ]
            },
            {
                "allocation": 100,
                "shareholder": [
                    {
                        "type": "individual",
                        "appointmentDate": "2001-09-17T00:00:00.000+1200",
                        "vacationDate": null,
                        "individualShareholder": {
                            "firstName": "John",
                            "middleNames": "James",
                            "lastName": "RAMBO",
                            "fullName": "RAMBO, John James"
                        },
                        "otherShareholder": null,
                        "shareholderAddress": {
                            "uniqueIdentifier": "13527416",
                            "startDate": "2001-09-17T00:00:00.000+1200",
                            "endDate": null,
                            "careOf": null,
                            "address1": "222 New World Street",
                            "address2": "Dallas",
                            "address3": "Wellington",
                            "address4": null,
                            "postCode": null,
                            "countryCode": null,
                            "addressType": null,
                            "pafId": null
                        }
                    }
                ]
            }
        ],
        "historicShareholder": []
    },
    "ultimateHoldingCompany": null,
    "australianCompanyNumber": null,
    "insolvencies": [],
    "removalCommenced": false
}

下面是我为上述响应创建的 POJO 类


import lombok.Data;

import java.util.Date;
import java.util.List;

public class Shareholders {
    Root root;
    Shareholding shareholding;
    ShareAllocation shareAllocation;
    Shareholder shareholder;
    ShareholderAddress shareholderAddress;
    IndividualShareholder individualShareholder;
}

@Data
class Root {
    public Object annualReturnFilingMonth;
    public Object financialReportFilingMonth;
    public Object nzsxCode;
    public Date annualReturnLastFiled;
    public boolean hasConstitutionFiled;
    public String countryOfOrigin;
    public String overseasCompany;
    public boolean extensiveShareholding;
    public Object stockExchangeListed;
    public Shareholding shareholding;
    public Object ultimateHoldingCompany;
    public Object australianCompanyNumber;
    public List<Object> insolvencies;
    public boolean removalCommenced;
}

@Data
class Shareholding{
    public int numberOfShares;
    public List<ShareAllocation> shareAllocation;
    public List<Object> historicShareholder;
}

@Data
class ShareAllocation{
    public int allocation;
    public List<Shareholder> shareholder;
}

@Data
class Shareholder{
    public String type;
    public Date appointmentDate;
    public Object vacationDate;
    public IndividualShareholder individualShareholder;
    public Object otherShareholder;
    public ShareholderAddress shareholderAddress;
}

@Data
class ShareholderAddress{
    public String uniqueIdentifier;
    public Date startDate;
    public Object endDate;
    public Object careOf;
    public String address1;
    public String address2;
    public String address3;
    public Object address4;
    public Object postCode;
    public Object countryCode;
    public Object addressType;
    public Object pafId;
}

@Data
class IndividualShareholder{
    public String firstName;
    public String middleNames;
    public String lastName;
    public String fullName;
}

现在我想做一个简单的测试,在其中验证响应中特定键的值。在这种情况下,它是“numberOfShares”

    "shareholding": {
        "numberOfShares": 300,
        "shareAllocation": [

这是我的测试:

package steps;

import lombok.var;

import io.restassured.response.Response;
import pojo.Shareholders;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

public class GetShareholderInformation {

    public static void numberOfSharesReturned(Response response, int numberOfSharesReturned) throws Throwable {
        System.out.println(response.getBody().prettyPrint());
        int numberOfSharesRet = numberOfSharesReturned;
        var shares = response.getBody().as(Shareholders.class);
        assertThat(shares.getClass(), equalTo(numberOfSharesRet));
    }
}

这是我运行测试时遇到的错误:

Step failed
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "annualReturnFilingMonth" (class pojo.Shareholders), not marked as ignorable (0 known properties: ])
 at [Source: (String)"{"annualReturnFilingMonth": null, "financialReportFilingMonth": null, "nzsxCode": null, "annualReturnLastFiled": "2002-05-29T12:15:56.000+1200", "hasConstitutionFiled": true, "countryOfOrigin": "NZ", "overseasCompany": "No", "extensiveShareholding": false, "stockExchangeListed": null, "shareholding": {"numberOfShares": 300, "shareAllocation": [{"allocation": 100, "shareholder": [{"type": "individual", "appointmentDate": "2001-09-17T00:00:00.000+1200", "vacationDate": null, "individualShareholder"[truncated 1815 chars]; line: 1, column: 33] (through reference chain: pojo.Shareholders["annualReturnFilingMonth"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:987)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1974)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1686)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1664)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:330)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)
    at com.fasterxml.jackson.databind.ObjectMapper$readValue$0.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
    at io.restassured.internal.path.json.mapping.JsonPathJackson2ObjectDeserializer.deserialize(JsonPathJackson2ObjectDeserializer.groovy:46)
    at io.restassured.path.json.mapping.JsonPathObjectDeserializer$deserialize.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
    at io.restassured.internal.mapping.Jackson2Mapper.deserialize(Jackson2Mapper.groovy:58)
    at io.restassured.mapper.ObjectMapper$deserialize.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
    at io.restassured.internal.mapping.ObjectMapping.parseWithJackson2(ObjectMapping.groovy:238)
    at io.restassured.internal.mapping.ObjectMapping$parseWithJackson2$0.callStatic(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:55)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:217)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:240)
    at io.restassured.internal.mapping.ObjectMapping.deserialize(ObjectMapping.groovy:59)
    at io.restassured.internal.mapping.ObjectMapping$deserialize.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at io.restassured.internal.RestAssuredResponseOptionsGroovyImpl.as(RestAssuredResponseOptionsGroovyImpl.groovy:231)
    at io.restassured.internal.RestAssuredResponseOptionsImpl.as(RestAssuredResponseOptionsImpl.java:169)
    at steps.GetShareholderInformation.numberOfSharesReturned(GetShareholderInformation.java:12)
    at tests.RestAssuredGeneric.validateNumberOfShares(RestAssuredGeneric.java:163)
    at steps.CommonSteps.iCanVerifyTheNumberOfSharesForThisCompanyIs(CommonSteps.java:53)
    at ✽.I can verify the number of shares for this company is 300(file:///Users/taliacallaghaninnovation/Projects/Callaghan-Innovation/DIP-Integration-Tests/nzbn-integration-tests/src/test/java/features/NZBNGetShareholderInfomtion.feature:8)

问题陈述:

  1. 从错误的角度来看,JSON 响应没有映射到 POJO 类。
  2. 在我的测试中,我不知道如何访问 Shareholders 类中的子类“Shareholding”,因为“Shareholding”是一个私有类。

标签: javajsonlombokpojojackson-databind

解决方案


推荐阅读