Deserialising complex nested Json using Jackson

I am struggling to deserialise complex nested Json data into Java objects I think my class structure is wrong. Here is my Json data:

    {
"resultsPerPage": 20,
"startIndex": 0,
"totalResults": 2,
"result": {
    "dataType": "CPE",
    "feedVersion": "1.0",
    "cpeCount": 2,
    "feedTimestamp": "2021-03-19T13:06",
    "cpes": [
        {
            "deprecated": false,
            "cpe23Uri": "cpe:2.3:o:microsoft:windows_10:1511:*:*:*:*:*:x64:*",
            "lastModifiedDate": "2015-12-09T17:28Z",
            "titles": [
                {
                    "title": "Microsoft Windows 10 1511 64-bit",
                    "lang": "en_US"
                }
            ],
            "refs": [
                {
                    "ref": "https://www.microsoft.com/en-us/",
                    "type": "Vendor"
                }
            ],
            "deprecatedBy": [],
            "vulnerabilities": [
                "CVE-2016-0174",
                "CVE-2016-0171"
            ]
        }

Here is the class I map the Json data to:

public class RESPONSE {

    Result result;
}

class Result {

    List<Cpes> cpes;
}

class Cpes {

    String cpe23Uri;
    List<Titles> titles;
    List<String> vulnerabilities;
}

class Titles{

    String title;
}

When I debug my code r in the below code is null and I think it’s because my RESPONSE class isn’t set up right.

        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        RESPONSE r = mapper.readValue(response.getContent(), RESPONSE.class);

        System.out.println(r);

Answer

Your object model should match the structure of the JSON you are trying to read. For example, it’ll have to look something like the following:

public class Response {
    private int resultsPerPage;
    private int startIndex;
    private int totalResults;
    private Result result;
    
    // Should include getters and setters
}

public class Result {
    private String dataType;
    private String feedVersion;
    private int cpeCount;
    private String feedTimestamp;
    private CPE[] cpes;

    // Should include getters and setters
}

public class CPE {
    private boolean deprecated;
    private String cpe23Uri;
    private String lastModifiedDate;
    private Title[] titles;
    private Ref[] refs;
    private String[] deprecatedBy;
    private String[] vulnerabilities;

    // Should include getters and setters
}

public class Title {
    private String title;
    private String lang;

    // Should include getters and setters
}

public class Ref {
    private String ref;
    private String type;

    // Should include getters and setters
}

Note that to keep the code sample short, I’ve omitted the getters and setters.

Edit: As Tugrul pointed out below, since fail on unknown property is disabled, it won’t fail if there are missing fields in your model. The only issue is the missing getters and setters.

Leave a Reply

Your email address will not be published. Required fields are marked *