【问题标题】:GSON map key value pairsGSON 映射键值对
【发布时间】:2016-12-05 15:52:50
【问题描述】:

使用 Retrofit 2 我使用了一个 API,它返回一个带有以下响应的 JSON 对象:

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

使用 GSON,我想将其序列化为以下类:

public class SecurityQuestionList {
    public String status;

    public Map<String, String> questions;
}

我已经用我的 Gson 对象注册了一个 TypeAdapter,但问题总是空的。

.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;
                    }
                })

我做错了什么?

【问题讨论】:

    标签: android json gson retrofit2


    【解决方案1】:

    在创建Retrofitinstance 时调用addConverterFactory(GsonConverterFactory.create()) 就足够了。

    【讨论】:

      【解决方案2】:

      “问题”是一个对象而不是数组。

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

      所以,你只需要改变

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

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

      这是我的测试代码。

      @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;
      }
      

      然后打印 {1=What was your childhood nickname?}

      【讨论】:

      • 如果我使用您的代码,我会收到一个错误:原因:java.lang.IllegalStateException:预期的 BEGIN_OBJECT 但在第 1 行第 29 列路径 $.questions 处是 BEGIN_ARRAY
      • 我的测试代码没问题。你的json数据是那种格式吗? Json数组是这样的。
      • [{"xxx":"yyy"},{"xxx":"yyy"}]
      • 你能把你的完整json数据。我得去睡觉了。我明天会回复。晚安。
      • 原来,我什至不需要 TypeAdapter。这个要求有个问题。请求的原始正文需要一个带有用户名字段的 JSON 对象。显然,在 Retrofit 中使用 @Body String username 不会将其包装在 JSON 对象中。不过感谢您的帮助!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多