java - 将 JSON 反序列化为未知类型的集合

标签 java json gson

我正在用 Java 编写一个程序,它通过调用某些方法向外部 API 发出请求。这些方法中的每一个都返回不同的 JSON 结构,它还取决于传递的参数。我的问题是是否有某种方法可以使用 Gson 反序列化响应字符串,而不必为每个方法编写不同的类。

如果不是 Gson,我可以使用哪个其他库?

谢谢。

最佳答案

My question is if there's some way to deserialize the response string using Gson without having to write a different class for each method.

是的,有。如果您不关心反序列化为特定 Java 类型的 JSON 结构只是一个包含键值对的对象,其中所有值都是 JSON 原语,那么该结构可以简单地反序列化为 Map<String, String>

请注意,Map<String, Object> 将不起作用,因为它没有为 Gson 反序列化提供足够的类型信息。 Gson 只会为每个值创建普通的 Object 实例——不是 StringInteger 实例,而是普通的 Object 实例。 JSON 中的实际值不会被反序列化。从表面上看,可以增强 Gson 以创建更多特定于类型的实例 JsonPrimitive 值似乎是合理的。例如,由于可以通过调用 JsonPrimitive 来确定 Boolean 是否是 isBoolean() ,那么人们可能希望 Gson 只构造一个 Boolean ,但事实并非如此——Gson 只是创建了一个空的且可能无用的 Object

这里有一个例子可以证明这一点。

input.json 内容:

{
  "one":"won",
  "too":22,
  "3":false
}

Foo.java:

import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    Gson gson = new Gson();
    Type mapOfStringObjectType = new TypeToken<Map<String, String>>() {}.getType();
    Map<String, String> map = gson.fromJson(new FileReader("input.json"), mapOfStringObjectType);
    System.out.println(map);
  }
}

这个例子的输出是 {3=false, one=won, too=22}

如果示例中的 Map 类型按照另一个答案中的建议更改为 HashMap<String, Object> ,则输出变为 {3=java.lang.Object@10b61fd1, one=java.lang.Object@24e2dae9, too=java.lang.Object@299209ea} ,这当然可能没有用。

如果出于某种原因必须将 HashMap<String, Object> 类型反序列化为,则需要自定义反序列化处理。

如果 JSON 结构不是一组简单的键值对,其中值都是 JSON 基元,但包括像 JSON 对象这样的复杂类型的值,即使将所有值转换为 Strings 是可以接受的,那么也有必要实现自定义反序列化处理。

不要犹豫,前往 the Gson Issues List 并提交增强请求,以改进 JSON 原语反序列化到适当的特定 Java Object 类型,或者有一个简单的机制来转换任何值——包括复杂的 JSON 类型,如对象和数组-- 在映射到 String 中,这样就不需要如上所述的自定义反序列化处理。

关于java - 将 JSON 反序列化为未知类型的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5697628/

相关文章:

java - 如何使用 GSON 和 Retrofit2 反序列化多形状 JSON 响应?

javascript - 如何从 JSON 创建数组?

java - 跳棋游戏 - 在 2D 数组中放置棋子 (Java)

java - 如何在 java6 中支持 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

java - 每当用户输入负数时,我需要帮助尝试重新输入值

json - 不能用 "encoding/json"覆盖鹰(类型接口(interface) {})

32 位服务器上的 PHP json_decode

java - 用于简单反序列化的 Jackson vs Gson

java - 在 java 中使用 GSON 解析 JSON 并填充 ListView

java - "java.security.cert.CertificateException: No name matching localhost found"无法在 Ubuntu 16.04 LTS 上解析