Gson deserialize json with varying value types

匿名 (未验证) 提交于 2019-12-03 01:08:02

问题:

I'm trying to deserialize a JSONArray with Gson, one the values' type can vary, the value "in_wanted" can be either a boolean or a JSONObject.

in_wanted as boolean:

{ "movies": [         {             "title": "example boolean",             "in_wanted": false         }     ]            } 

in_wanted as JSONObject:

{ "movies": [         {             "title": "example object",             "in_wanted": {                 "profile": {                     "value": false                 }             }         }     ]            } 

I need the object whenever it's available and i need a deserializer to return null whenever the value of "in_wanted" is a boolean. What would be the best way to do this with Gson?

回答1:

You can do this with custom deserializer. At the start we should create data model which can represent your JSON.

class JsonEntity {      private List movies;      public List getMovies() {         return movies;     }      public void setMovies(List movies) {         this.movies = movies;     }      @Override     public String toString() {         return "JsonEntity [movies=" + movies + "]";     } }  class Movie {      private String title;     private Profile in_wanted;      public String getTitle() {         return title;     }      public void setTitle(String title) {         this.title = title;     }      public Profile getIn_wanted() {         return in_wanted;     }      public void setIn_wanted(Profile in_wanted) {         this.in_wanted = in_wanted;     }      @Override     public String toString() {         return "Movie [title=" + title + ", in_wanted=" + in_wanted + "]";     } }  class Profile {      private boolean value;      public boolean isValue() {         return value;     }      public void setValue(boolean value) {         this.value = value;     }      @Override     public String toString() {         return String.valueOf(value);     } } 

Now when we have all needed classes we should implement new custom deserializer:

class ProfileJsonDeserializer implements JsonDeserializer {     @Override     public Profile deserialize(JsonElement jsonElement, Type type,             JsonDeserializationContext context) throws JsonParseException {         if (jsonElement.isJsonPrimitive()) {             return null;         }          return context.deserialize(jsonElement, JsonProfile.class);     } }  class JsonProfile extends Profile {  } 

Please have a look on JsonProfile class. We have to create it to avoid "deserialization loop" (tricky part).

And now we can test our solution with test method:

GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Profile.class, new ProfileJsonDeserializer()); Gson gson = builder.create();  JsonEntity jsonEntity = gson.fromJson(new FileReader("/tmp/json.txt"),         JsonEntity.class); System.out.println(jsonEntity); 


回答2:

You could do a manual parsing, something like:

JsonParser parser = new JsonParser(); JsonObject rootObject = parser.parse(yourJsonString).getAsJsonObject(); JsonObject movieObject = rootObject                            .getAsJsonArray("movies")                            .get(0).getAsJsonObject(); JsonElement inWantedElement = movieObject.get("in_wanted");  //Check if "in_wanted" element is a boolean or an object if (inWantedElement.isJsonObject()) {     //Process the element as an object...     //for example get the element "value"...     boolean value = inWantedElement                       .getAsJsonObject()                       .getAsJsonObject("profile")                       .getAsJsonPrimitive("value")                       .getAsBoolean(); } else if (inWantedElement.isJsonPrimitive()) {     //Process the element as a boolean...     boolean inWanted = inWantedElement.getAsBoolean(); } 

Note: see Gson API documentation for further info about types JsonObject, JsonArray, JsonElement, and so on...



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!