【问题标题】:GSON if deserialized string contains another JSON如果反序列化的字符串包含另一个 JSON,则为 GSON
【发布时间】:2016-06-09 18:21:11
【问题描述】:

不是那么典型的情况。

我有来自服务器的下一个 JSON 字符串:
{"SomeElements":[{"Id":"Title","Info":"{\"Text\": \"Sometext\"}"}]}

这是它的图形表示:

问题是字符串Info 包含另一个JSON 字符串。
这是我的 POJO:

public class Test {
    private ArrayList<SomeElement> SomeElements;

    public class SomeElement {
        private String Id;
        private String Info;
    }
}

问题 - 有没有办法将Info 字符串解析为我的 POJO 中的 HashMap(例如)而不是字符串?

如果我尝试将其声明为HashMap&lt;String, String&gt;,则会出现错误"Expected OBJECT, but was STRING"

处理此问题的最佳方法是什么?自定义反序列化器是唯一的方法吗?


!! 这个问题不是重复的!!
我无法更改来自服务器的 JSON 响应。
请仔细阅读 - 我在问,是否可以将 Info 字符串解析为另一个 JSON,而不是字符串。

解决方案我最终选择了下一个。
我声明了private LinkedTreeMap&lt;String, String&gt; infoMap; 并首先将Info 反序列化为字符串。那么:

public LinkedTreeMap<String, String> getInfoMap() {
            if (infoMap == null) {
                infoMap = new Gson().fromJson(info, new TypeToken<Map<String, String>>(){}.getType());
            }
            return infoMap;
        }

我想这比编写自定义反序列化器要容易得多,但在更复杂的情况下,自定义反序列化器可能是唯一的选择。
所以在一般情况下@arjabbar 的答案会更好。

【问题讨论】:

  • 你为什么要这么做?
  • 简单——我想把服务器端的响应解析成一个可用的类。

标签: android json gson


【解决方案1】:

您有几个选择,但我认为您最好的选择是制作一个自定义解串器。这不是你唯一的方法,但是一旦你习惯了编写反序列化器,它就不会那么糟糕了。

Here are some decent examples.

【讨论】:

  • 是的,我想自定义解串器将是唯一的选择。 Info 是一个字符串的主要问题 - 如果它是嵌套的 JSON,那就很容易了。
【解决方案2】:

这里的 Info 也是对象。所以你需要为信息创建类。

public class Test {
    private ArrayList<SomeElement> SomeElements;

    public class SomeElement {
        private String Id;
        private Info info;
    }

}
class Info{
private String text;
private String sometext;
//getter and setter 
}

【讨论】:

  • 它不起作用,因为 Info 是一个字符串:com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 46
【解决方案3】:

您还需要为Info 对象创建一个类,以便GSON 为您反序列化它。

试试这个:

public class EntireJsonObject {
    private ArrayList<SomeElement> someElements;
}

public class SomeElement {
    private String id;
    private Info info;
}

public class Info {
    private String text;
}

您需要让GSON 将来自服务器的JSON 响应反序列化为EntireJsonObjectGSON 将为您处理所有内部转换和反序列化。现在您可以通过来自Info 对象的getter 访问“SomeText”。

请务必注意,您的变量名称不必必须与 JSON 响应中返回的键完全匹配。 GSON 将根据各种方案(camelCase、under_scores 等等)翻译变量名。您可以指定创建对象时使用的转换协议GSON

如果您绝对希望将Info 用作HashMap&lt;String, String&gt;,则必须单独为此编写反序列化程序。我会检查 GSON 文档,因为您可能不必为整个 JSON 响应编写自定义反序列化器,而只需为内部对象编写。

【讨论】:

  • 谢谢,但它不工作 - 原因是一样的 - 信息是一个字符串:com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 46
  • @GoltsevEugene 啊,我明白了。我没有注意到整个字段都被封装在引号中。在这种情况下,您将不得不使用自定义反序列化器作为上面提到的 arjabbar
猜你喜欢
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-28
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多