Ventis
Ventis

Reputation: 488

GSON map key value pairs

using Retrofit 2 I consuming an API that gives returns a JSON object with the following response:

{
  "status": "ok",
  "questions": {
    "1": "What was your childhood nickname?"
  }
}

Using GSON, I wanted to serialise this to the following class:

public class SecurityQuestionList {
    public String status;

    public Map<String, String> questions;
}

I've registered a TypeAdapter with my Gson object but the questions is always empty.

.registerTypeAdapter(new TypeToken<Map<String, String>>() {}.getType(), new TypeAdapter<Map<String, String>>() {
                    @Override
                    public void write(JsonWriter out, Map<String, String> value) throws IOException {

                    }

                    @Override
                    public Map<String, String> read(JsonReader in) throws IOException {
                        Map<String, String> map = new HashMap<String, String>();
                        try {
                            in.beginArray();
                            while (in.hasNext()) {
                                map.put(in.nextString(), in.nextString());
                            }
                            in.endArray();
                        } catch (IOException ex) {

                        }

                        return map;
                    }
                })

What am I doing wrong?

Upvotes: 3

Views: 1341

Answers (2)

ittianyu
ittianyu

Reputation: 509

The "questions" is a object instead of array.

"questions": {
    "1": "What was your childhood nickname?"
  }

So, you just need change

in.beginArray();
while (in.hasNext()) {
    map.put(in.nextString(), in.nextString());
}
in.endArray();

to

in.beginObject();
while (in.hasNext()) {
    map.put(in.nextName(), in.nextString());
}
in.endObject();

Here are my test code.

@Test
public void gson() {
    String str = "{\n" +
            "  \"status\": \"ok\",\n" +
            "  \"questions\": {\n" +
            "    \"1\": \"What was your childhood nickname?\"\n" +
            "  }\n" +
            "}";
    Gson gson = new GsonBuilder().registerTypeAdapter(new TypeToken<Map<String, String>>() {
    }.getType(), new TypeAdapter<Map<String, String>>() {
        @Override
        public void write(JsonWriter out, Map<String, String> value) throws IOException {
        }
        @Override
        public Map<String, String> read(JsonReader in) throws IOException {
            Map<String, String> map = new HashMap<String, String>();
            try {
                in.beginObject();
                while (in.hasNext()) {
                    map.put(in.nextName(), in.nextString());
                }
                in.endObject();
            } catch (IOException ex) {
            }
            return map;
        }
    }).create();
    SecurityQuestionList securityQuestionList = gson.fromJson(str, SecurityQuestionList.class);
    System.out.println(securityQuestionList.questions);
}

public static class SecurityQuestionList {
    public String status;
    public Map<String, String> questions;
}

And print {1=What was your childhood nickname?}

Upvotes: 1

John O&#39;Reilly
John O&#39;Reilly

Reputation: 10350

It should be sufficient to call addConverterFactory(GsonConverterFactory.create()) when creating Retrofitinstance.

Upvotes: 1

Related Questions