0

Json string:

  [  
       //Object 1

       {  
          TypeName:"CheckSpecificDday",
          SpecificDay:"20160413",
          Lunar:1
       },

       {  
          TypeName:"CheckSpecificDday",
          SpecificDay:"20160414",
          Lunar:1
       },

       //Object 2

       {  
          TypeName:"CheckEveryDayDday",
          StartDate:"20160413",
          EndDate:"20260417",
          Interval:1,
          StartOption:"D",
          HolidayCondition:1
       },

       //Object 3

       {  
          TypeName:"CheckEveryDdayOfWeek",
          StartDate:"20160413",
          EndDate:"",
          Interval:1,
          SpecificDayOfWeek:"3",
          HolidayCondition:1
       },

       //Object 4

       {  
          TypeName:"CheckEveryMonthSpecificDday",
          StartDate:"20160413",
          EndDate:"",
          Interval:1,
          SpecificDD:"13,14",
          HolidayCondition:1
       },

       //Object 5

       {  
          TypeName:"CheckEveryYearWeek",
          StartDate:"20160413",
          EndDate:"",
          Interval:1,
          SpecificMMnthWeek:"0433",
          HolidayCondition:1
       }

    ]

I have a Json array like the above. What I want is to parse it to different object types with Gson (as I commented to make it clearer), but I dont know how to do that. Please help me. Thank you in advance!

4
  • Can you post link API. I will create a example project Commented Apr 13, 2016 at 4:20
  • Gson will not do this for you automatically. You'll have to write some code that looks at TypeName and makes a decision about which Java object its data should populate. Commented Apr 13, 2016 at 4:33
  • I know that, but I dont know how. Can you give me some example? Commented Apr 13, 2016 at 4:44
  • You can post link your API. example link.com/api Commented Apr 13, 2016 at 4:51

1 Answer 1

20

I think there are lots of simmilar questions on SO. One, Two

One way to parse this is to use simple

Object[] result = new Gson().fromJson(json, Object[].class);

But this will give you objects of LinkedTreeMap<Integer, LinkedTreeMap<String, String>> or something like this. You can use it, but its kinda hard and you will also have problems with your integers comming as doubles.

The other approach is to create custom interface or abstract class with TypeName field if you need it:

private interface CheckInterface{}

and implement it with every POJO classes of object types you have:

private static class CheckEveryDayBase implements CheckInterface{
    private String StartDate;
    private String EndDate;
    private int Interval;
    private int HolidayCondition;
}

private static class CheckSpecificDday implements CheckInterface{
    private String SpecificDay;
    private int Lunar;
}

private static class CheckEveryDayDday extends CheckEveryDayBase{
    private String StartOption;
}

private static class CheckEveryDdayOfWeek extends CheckEveryDayBase{
    private String SpecificDayOfWeek;
}

private static class CheckEveryMonthSpecificDday extends CheckEveryDayBase{
    private String SpecificDD;
}

private static class CheckEveryYearWeek extends CheckEveryDayBase{
    private String SpecificMMnthWeek;
}

Then create custom desrializer for your CheckInterface:

public static class CheckInterfaceDeserializer implements JsonDeserializer<CheckInterface>{

    @Override
    public CheckInterface deserialize(JsonElement json, Type typeOfT,
                       JsonDeserializationContext context) throws JsonParseException {
        JsonObject jObject = (JsonObject) json;
        JsonElement typeObj = jObject.get("TypeName");

        if(typeObj!= null ){
            String typeVal = typeObj.getAsString();

            switch (typeVal){
                case "CheckSpecificDday":
                   return context.deserialize(json, CheckSpecificDday.class);
                case "CheckEveryDayDday":
                    return context.deserialize(json, CheckEveryDayDday.class);
                case "CheckEveryDdayOfWeek":
                    return context.deserialize(json, CheckEveryDdayOfWeek.class);
                case "CheckEveryMonthSpecificDday":
                    return context.deserialize(json, CheckEveryMonthSpecificDday.class);
                case "CheckEveryYearWeek":
                    return context.deserialize(json, CheckEveryYearWeek.class);
            }
        }

        return null;
    }
}

Here is how you can use this:

GsonBuilder builder = new GsonBuilder();

// Register custom deserializer for CheckInterface.class
builder.registerTypeAdapter(CheckInterface.class, new CheckInterfaceDeserializer());
Gson gson = builder.create();

CheckInterface[] result2 = gson.fromJson(json, CheckInterface[].class);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.