0

I'm trying to learn the process of packaging. While using the Jackson ObjectMapper to parse my JSON file, I receive an UnrecognizedPropertyException.

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "usa" (class com.stateparser.database.StateGroup), not marked as ignorable (one known property: "states"])
 at [Source: (File); line: 2, column: 11] (through reference chain: com.stateparser.database.StateGroup["usa"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1127)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1989)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1700)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1678)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:319)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3494)
    at com.stateparser.Main.main(Main.java:20)

I'm not sure where I created the error. I was attempting to create a list of state objects. With the list of object, loop through it and print the data for each object to the console.

Following the accepted answer of a previous question asked

Jackson ObjectMapper JSON to Java Object RETURNS NULL Values

and the process of packaging by layer; I have laid out my project as follows:

The JSON file which contains the list of States:

{
  "usa": [
    {
      "abbr": "AL",
      "name": "Alabama",
      "capital": "Montgomery",
      "latitude": "32.361538",
      "longitude": "-86.279118"
    },
    {
      "abbr": "AK",
      "name": "Alaska",
      "capital": "Juneau",
      "latitude": "58.301935",
      "longitude": "-134.419740"
    },
    {
      "abbr": "AZ",
      "name": "Arizona",
      "capital": "Phoenix",
      "latitude": "33.448457",
      "longitude": "-112.073844"
    },
    {
      "abbr": "AR",
      "name": "Arkansas",
      "capital": "Little Rock",
      "latitude": "34.736009",
      "longitude": "-92.331122"
    },
    {
      "abbr": "CA",
      "name": "California",
      "capital": "Sacramento",
      "latitude": "38.555605",
      "longitude": "-121.468926"
    },
    {
      "abbr": "CO",
      "name": "Colorado",
      "capital": "Denver",
      "latitude": "39.7391667",
      "longitude": "-104.984167"
    },
    {
      "abbr": "CT",
      "name": "Connecticut",
      "capital": "Hartford",
      "latitude": "41.767",
      "longitude": "-72.677"
    },
    {
      "abbr": "DE",
      "name": "Delaware",
      "capital": "Dover",
      "latitude": "39.161921",
      "longitude": "-75.526755"
    },
    {
      "abbr": "FL",
      "name": "Florida",
      "capital": "Tallahassee",
      "latitude": "30.4518",
      "longitude": "-84.27277"
    },
    {
      "abbr": "GA",
      "name": "Georgia",
      "capital": "Atlanta",
      "latitude": "33.76",
      "longitude": "-84.39"
    },
    {
      "abbr": "HI",
      "name": "Hawaii",
      "capital": "Honolulu",
      "latitude": "21.30895",
      "longitude": "-157.826182"
    },
    {
      "abbr": "ID",
      "name": "Idaho",
      "capital": "Boise",
      "latitude": "43.613739",
      "longitude": "-116.237651"
    },
    {
      "abbr": "IL",
      "name": "Illinois",
      "capital": "Springfield",
      "latitude": "39.783250",
      "longitude": "-89.650373"
    },
    {
      "abbr": "IN",
      "name": "Indiana",
      "capital": "Indianapolis",
      "latitude": "39.790942",
      "longitude": "-86.147685"
    },
    {
      "abbr": "IA",
      "name": "Iowa",
      "capital": "Des Moines",
      "latitude": "41.590939",
      "longitude": "-93.620866"
    },
    {
      "abbr": "KS",
      "name": "Kansas",
      "capital": "Topeka",
      "latitude": "39.04",
      "longitude": "-95.69"
    },
    {
      "abbr": "KY",
      "name": "Kentucky",
      "capital": "Frankfort",
      "latitude": "38.197274",
      "longitude": "-84.86311"
    },
    {
      "abbr": "LA",
      "name": "Louisiana",
      "capital": "Baton Rouge",
      "latitude": "30.45809",
      "longitude": "-91.140229"
    },
    {
      "abbr": "ME",
      "name": "Maine",
      "capital": "Augusta",
      "latitude": "44.323535",
      "longitude": "-69.765261"
    },
    {
      "abbr": "MD",
      "name": "Maryland",
      "capital": "Annapolis",
      "latitude": "38.972945",
      "longitude": "-76.501157"
    },
    {
      "abbr": "MA",
      "name": "Massachusetts",
      "capital": "Boston",
      "latitude": "42.2352",
      "longitude": "-71.0275"
    },
    {
      "abbr": "MI",
      "name": "Michigan",
      "capital": "Lansing",
      "latitude": "42.7335",
      "longitude": "-84.5467"
    },
    {
      "abbr": "MN",
      "name": "Minnesota",
      "capital": "Saint Paul",
      "latitude": "44.95",
      "longitude": "-93.094"
    },
    {
      "abbr": "MS",
      "name": "Mississippi",
      "capital": "Jackson",
      "latitude": "32.320",
      "longitude": "-90.207"
    },
    {
      "abbr": "MO",
      "name": "Missouri",
      "capital": "Jefferson City",
      "latitude": "38.572954",
      "longitude": "-92.189283"
    },
    {
      "abbr": "MT",
      "name": "Montana",
      "capital": "Helana",
      "latitude": "46.595805",
      "longitude": "-112.027031"
    },
    {
      "abbr": "NE",
      "name": "Nebraska",
      "capital": "Lincoln",
      "latitude": "40.809868",
      "longitude": "-96.675345"
    },
    {
      "abbr": "NV",
      "name": "Nevada",
      "capital": "Carson City",
      "latitude": "39.160949",
      "longitude": "-119.753877"
    },
    {
      "abbr": "NH",
      "name": "New Hampshire",
      "capital": "Concord",
      "latitude": "43.220093",
      "longitude": "-71.549127"
    },
    {
      "abbr": "NJ",
      "name": "New Jersey",
      "capital": "Trenton",
      "latitude": "40.221741",
      "longitude": "-74.756138"
    },
    {
      "abbr": "NM",
      "name": "New Mexico",
      "capital": "Santa Fe",
      "latitude": "35.667231",
      "longitude": "-105.964575"
    },
    {
      "abbr": "NY",
      "name": "New York",
      "capital": "Albany",
      "latitude": "42.659829",
      "longitude": "-73.781339"
    },
    {
      "abbr": "NC",
      "name": "North Carolina",
      "capital": "Raleigh",
      "latitude": "35.771",
      "longitude": "-78.638"
    },
    {
      "abbr": "ND",
      "name": "North Dakota",
      "capital": "Bismarck",
      "latitude": "48.813343",
      "longitude": "-100.779004"
    },
    {
      "abbr": "OH",
      "name": "Ohio",
      "capital": "Columbus",
      "latitude": "39.962245",
      "longitude": "-83.000647"
    },
    {
      "abbr": "OK",
      "name": "Oklahoma",
      "capital": "Oklahoma City",
      "latitude": "35.482309",
      "longitude": "-97.534994"
    },
    {
      "abbr": "OR",
      "name": "Oregon",
      "capital": "Salem",
      "latitude": "44.931109",
      "longitude": "-123.029159"
    },
    {
      "abbr": "PA",
      "name": "Pennsylvania",
      "capital": "Harrisburg",
      "latitude": "40.269789",
      "longitude": "-76.875613"
    },
    {
      "abbr": "RI",
      "name": "Rhode Island",
      "capital": "Providence",
      "latitude": "41.82355",
      "longitude": "-71.422132"
    },
    {
      "abbr": "SC",
      "name": "South Carolina",
      "capital": "Columbia",
      "latitude": "34.000",
      "longitude": "-81.035"
    },
    {
      "abbr": "SD",
      "name": "South Dakota",
      "capital": "Pierre",
      "latitude": "44.367966",
      "longitude": "-100.336378"
    },
    {
      "abbr": "TN",
      "name": "Tennessee",
      "capital": "Nashville",
      "latitude": "36.165",
      "longitude": "-86.784"
    },
    {
      "abbr": "TX",
      "name": "Texas",
      "capital": "Austin",
      "latitude": "30.266667",
      "longitude": "-97.75"
    },
    {
      "abbr": "UT",
      "name": "Utah",
      "capital": "Salt Lake City",
      "latitude": "40.7547",
      "longitude": "-111.892622"
    },
    {
      "abbr": "VT",
      "name": "Vermont",
      "capital": "Montpelier",
      "latitude": "44.26639",
      "longitude": "-72.57194"
    },
    {
      "abbr": "VA",
      "name": "Virginia",
      "capital": "Richmond",
      "latitude": "37.54",
      "longitude": "-77.46"
    },
    {
      "abbr": "WA",
      "name": "Washington",
      "capital": "Olympia",
      "latitude": "47.042418",
      "longitude": "-122.893077"
    },
    {
      "abbr": "WV",
      "name": "West Virginia",
      "capital": "Charleston",
      "latitude": "38.349497",
      "longitude": "-81.633294"
    },
    {
      "abbr": "WI",
      "name": "Wisconsin",
      "capital": "Madison",
      "latitude": "43.074722",
      "longitude": "-89.384444"
    },
    {
      "abbr": "WY",
      "name": "Wyoming",
      "capital": "Cheyenne",
      "latitude": "41.145548",
      "longitude": "-104.802042"
    }
  ]
}

The Java class file which describes a state:

package com.stateparser.database;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class State {
    private String abbr;
    private String name;
    private String capital;
    private String latitude;
    private String longitude;

    public State() {
        // DEFAULT CONSTRUCTOR
    }

    public State(String abbr, String name, String capital, String latitude, String longitude) {
        this.abbr = abbr;
        this.name = name;
        this.capital = capital;
        this.latitude = latitude;
        this.longitude = longitude;
    }

    @Override
    public String toString() {
        return name + "{" +
                "name='" + name + "'" +
                "capital='" + capital + "'" +
                "abbr='" + abbr + "'" +
                "latitude='" + latitude + "'" +
                "longitude='" + longitude + "'}";
    }

    public String getAbbr() {
        return abbr;
    }

    public void setAbbr(String abbr) {
        this.abbr = abbr;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCapital() {
        return capital;
    }

    public void setCapital(String capital) {
        this.capital = capital;
    }

    public String getLatitude() {
        return latitude;
    }

    public void setLatitude(String latitude) {
        this.latitude = latitude;
    }

    public String getLongitude() {
        return longitude;
    }

    public void setLongitude(String longitude) {
        this.longitude = longitude;
    }
}

The Java class which creates a list of objects based on my state class:

package com.stateparser.database;

import java.util.List;

public class StateGroup {
    private List<State> states;

    public List<State> getStates() {
        return states;
    }

    public void setStates(List<State> states) {
        this.states = states;
    }
}

The main Java class:

package com.stateparser;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.stateparser.database.State;
import com.stateparser.database.StateGroup;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        File file = new File("src/main/resources/States.json");

        ObjectMapper mapper = new ObjectMapper();

        try {
            StateGroup States = mapper.readValue(file, StateGroup.class);

            List<State> allTerritories = States.getStates();

            allTerritories.forEach(states -> {
                System.out.println(states);
            });
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I'm looking for some help to understand why I receive the UnrecognizedPropertyException.

TroyPilewski
  • 359
  • 8
  • 27
  • It is because of the json array named "usa" at top level. What you should get is what inside the array. Or you could also create a class "Usa" that contains an array of State field then deserialize with this class – Otourou Da Costa Feb 14 '22 at 01:53
  • So I would need a country class? I tried to copy what I did based on the link provided. The only difference was I didn't package by layer in that example. – TroyPilewski Feb 14 '22 at 02:09

1 Answers1

0

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "usa"

You are trying to map the JSON to the StateGroup object, but the Java object doesn't have a "usa" field.

Two options:

  1. Rename the states field to usa:
public class StateGroup {
    private List<State> usa;

    public List<State> getUsa() {
        return usa;
    }

    public void setUsa(List<State> usa) {
        this.usa = usa;
    }
}
  1. Add the @JsonProperty("usa") annotation to the states field:
import com.fasterxml.jackson.annotation.JsonProperty;

public class StateGroup {
    @JsonProperty("usa")
    private List<State> states;

    public List<State> getStates() {
        return states;
    }

    public void setStates(List<State> states) {
        this.states = states;
    }
}
badjr
  • 2,166
  • 3
  • 20
  • 31
  • Could you explain this a bit further? I'm still trying to learn this and don't understand what is different from the link that I provided in my question and this question other than they way I packaged them. – TroyPilewski Feb 14 '22 at 18:20
  • You were very close to having the correct Java class structure that matches the JSON structure. The only thing that was missing was matching the "usa" field from the JSON to the corresponding Java field. So you have the two options described in the answer. Does that help clear it up? – badjr Feb 14 '22 at 21:41
  • Thank you. I went with option #2. Is there some resources I could read to understand what exactly the annotations mean? Additionally, I don't really understand what I did differently between the two projects: the one in the referenced link and the one in this question. – TroyPilewski Feb 16 '22 at 16:25
  • [Here](https://stackoverflow.com/questions/12583638/when-is-the-jsonproperty-property-used-and-what-is-it-used-for) is a relevant Stackoverflow question about the `@JsonProperty` annotation. And [here](https://fasterxml.github.io/jackson-annotations/javadoc/2.8/com/fasterxml/jackson/annotation/JsonProperty.html) is the official documentation for it. – badjr Feb 16 '22 at 20:27
  • In the link to the previous question you asked on this, there was an [answer](https://stackoverflow.com/a/70222303/1461484) where it suggested adding a `SpeciesGroup` class that held a list of `Species`. If this is what you added to your original code, then this works because the `species` field name matches `"species"` in the JSON String as well. Had the `species` field in the Java code had been named something different, say `genus`, then you would have run into the same error. – badjr Feb 16 '22 at 20:33
  • Thank you. I think that I understand. If I change 'usa' in the JSON to 'states'. The way that I wrote would have worked. – TroyPilewski Feb 17 '22 at 00:34
  • Yep, exactly. That's another option that could make it work. – badjr Feb 17 '22 at 01:18