可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
  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...