JSON array in GSON parses, but objects are empty

后端 未结 1 1033
醉梦人生
醉梦人生 2021-01-15 16:30

i am attempting to turn a json string into objects with gson.

I have a very simple example below, and it runs, but the resulting answer is empty, ie: my Answer objec

相关标签:
1条回答
  • 2021-01-15 17:28

    Because your JSON doesn't match your class.

    Your JSON right now is an array of objects, each containing an answer object as a field.

    Your JSON the way you have things would need to look like:

    String jsonOutput = "[{\"text\":\"text1\"},{\"text\":\"text2\"}]";
    

    Edit to add from comments:

    If you can't change the output, you need a "wrapper". Something like:

    public class AnswerWrapper {
        public Answer answer;
    
        // etc
    }
    

    And use an array of those. That is what the JSON will map to. It can't see them as Answer objects because ... they're not.

    One More Edit to Add: Your other option is to write custom deserializers for your classes. I'm a bit mixed on whether you should do this or not, but it will work. The reason I say that is that you have JSON that isn't an array of Answer objects, but you want it to be. I think I'd be annoyed if I came across this in production code because without understanding what was going on it could be confusing.

    With that caveat being said, you can create a custom JsonDeserializer and use GsonBuilder:

    class AnswerDeserializer implements JsonDeserializer<Answer> {
    
        public Answer deserialize(JsonElement je, Type type, 
                                  JsonDeserializationContext jdc) 
                                       throws JsonParseException {
    
            return new Answer(je.getAsJsonObject().get("answer")
                                .getAsJsonObject().get("text").getAsString());
        }
    
    }
    

    Then your code would look like:

    public static void main(String[] args) throws Exception{
    
        String jsonOutput = "[{\"answer\":{\"text\":\"text1\"}},{\"answer\":{\"text\":\"text2\"}} ]";
    
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Answer.class, new AnswerDeserializer());
    
        Gson gson = gsonBuilder.create();
    
        Answer[] a = gson.fromJson(jsonOutput, Answer[].class);
    
        for(Answer i:a) {
            System.out.println(i.text);
        }       
    }
    

    If it were me, and I had JSON that wasn't what I needed it to be but wanted to use GSON to directly serialize/deserialize I'd create the Answer class as a wrapper that hid the details:

    /**
     *  Due to how our JSON is being provided we created an inner
     *  class. 
     **/ 
    public class Answer {
    
        private RealAnswer answer;
    
        private class RealAnswer {
    
            public String text;
        }
    
        ...
    }
    

    With the public getters/setters for Answer accessing the private RealAnswer. It just seems way cleaner and easier to understand for the next guy.

    0 讨论(0)
提交回复
热议问题