简体   繁体   中英

Parse Json to object containing objects

I have the following code with json, that I got from accuweather

{  
 "Headline":{  
      "EffectiveDate":"2019-07-29T07:00:00+06:00",
      "EffectiveEpochDate":1564362000,
      "Severity":3,
      "Text":"The heat wave will continue through Friday",
      "Category":"heat",
      "EndDate":"2019-08-02T19:00:00+06:00",
      "EndEpochDate":1564750800
   },
   "DailyForecasts":[  
      {  
         "Date":"2019-07-29T07:00:00+06:00",
         "EpochDate":1564362000,
         "Temperature":{  
            "Minimum":{  
               "Value":19.1,
               "Unit":"C",
               "UnitType":17
            },
            "Maximum":{  
               "Value":36.7,
               "Unit":"C",
               "UnitType":17
            }
         },
         "Day":{  
            "Icon":30,
            "IconPhrase":"Hot",
            "HasPrecipitation":false
         },
         "Night":{  
            "Icon":35,
            "IconPhrase":"Partly cloudy",
            "HasPrecipitation":false
         },
         "Sources":[  
            "AccuWeather"
         ]
      }
   ]
}

I try to parse this object to the POJO via jackson

public static void main( String[] args )
{
    String x = "{\"Headline\":{\"EffectiveDate\":\"2019-07-29T07:00:00+06:00\",\"EffectiveEpochDate\":1564362000,\"Severity\":3,\"Text\":\"The heat wave will continue through Friday\",\"Category\":\"heat\",\"EndDate\":\"2019-08-02T19:00:00+06:00\",\"EndEpochDate\":1564750800},\"DailyForecasts\":[{\"Date\":\"2019-07-29T07:00:00+06:00\",\"EpochDate\":1564362000,\"Temperature\":{\"Minimum\":{\"Value\":19.1,\"Unit\":\"C\",\"UnitType\":17},\"Maximum\":{\"Value\":36.7,\"Unit\":\"C\",\"UnitType\":17}},\"Day\":{\"Icon\":30,\"IconPhrase\":\"Hot\",\"HasPrecipitation\":false},\"Night\":{\"Icon\":35,\"IconPhrase\":\"Partly cloudy\",\"HasPrecipitation\":false},\"Sources\":[\"AccuWeather\"]}]}";
    ObjectMapper objectMapper = new ObjectMapper();

    try {
        Weather weather = objectMapper.readValue(x, Weather.class);

        System.out.println(weather);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

I have all the models specified in the json like Headline , array of DailyForecasts , Temperature that consists of TemperatureItems (named minimum and maximum as in json) and etc, all of them have private fields and public constructor, getters and setters. However I do not have some of the fields as I want to omit them(Day, Night, EpochDate, Source).

When I run the program I get the error

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of test.models.weather.Weather (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

I have also tried Gson but it return object with Null values

Am I doing something wrong? Is there another way to do it?

Edit : These are the models, @LazerBass was right, as I firstly didn't include default constructors, now the error has changed:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Headline" (class test.models.weather.Weather), not marked as ignorable (2 known properties: "headline", "dailyForecasts"])

public class TemperatureItem {
    public double value;
    public String unit;
    public String unitType;

    public TemperatureItem() {

    }

    //Getters and setters
}


public class Temperature {
    private TemperatureItem maximum;
    private TemperatureItem minimum;

    public Temperature(TemperatureItem maximum, TemperatureItem minimum) {
        this.maximum = maximum;
        this.minimum = minimum;
    }

    public Temperature() {

    }
    //Getters and setters
}

public class DailyForecasts {
    private LocalDateTime date;
    private Temperature temperature;

    public DailyForecasts(LocalDateTime date, Temperature temperature) {
        this.date = date;
        this.temperature = temperature;
    }

    public DailyForecasts() {

    }
    //Getters and setters
}

public class Headline {
    private LocalDateTime effectiveDate;
    private int severity;
    private String text;
    private String category;
    private LocalDateTime endDate;

    public Headline() {

    }

    public Headline(LocalDateTime effectiveDate, Integer severity, String text, String category, LocalDateTime endDate) {
        this.effectiveDate = effectiveDate;
        this.severity = severity;
        this.text = text;
        this.category = category;
        this.endDate = endDate;
    }
    //Getters and setters
}

public class Weather {
        private Headline headline;
        private DailyForecasts[] dailyForecasts;

        public Weather() {

        }
        public Weather(Headline headline, DailyForecasts[] dailyForecasts) {
            this.headline = headline;
            this.dailyForecasts = dailyForecasts;
        }
        //Getters and setters
}

I have found out, that if I convert json string to lowercase, I can get some values, although Array and LocalDateTime weren't parsed

Judging from the exception message I would guess that your Weather class is laking an no-argument constructor. Try adding one. Eg

public class Weather {
    public Weather() {
        // no arg constructor needed for jackson
    }
}

To generate the Weather classes and its corresponding classes, use the following link and select the source type as json. It will generate the required classes as per the json string.

http://www.jsonschema2pojo.org/

After generating the classes, you can annotate the fields with @JsonIgnore which are not required.

When Jackson fails with message like " no Creators, like default construct, exist " it needs default, public no-argument constructor for each POJO class you have in your model.

When it fails with message like " Unrecognized field ... not marked as ignorable ... " you need to disable FAIL_ON_UNKNOWN_PROPERTIES feature.

See also:

  1. Jackson Unmarshalling JSON with Unknown Properties
  2. jackson delay deserializing field

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM