Gson deserialize json with varying value types

后端 未结 2 1321
长情又很酷
长情又很酷 2020-12-10 07:43

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 JSONOb

相关标签:
2条回答
  • 2020-12-10 08:14

    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...

    0 讨论(0)
  • 2020-12-10 08:17

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

    class JsonEntity {
    
        private List<Movie> movies;
    
        public List<Movie> getMovies() {
            return movies;
        }
    
        public void setMovies(List<Movie> 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<Profile> {
        @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);
    
    0 讨论(0)
提交回复
热议问题