我正在用Java编写一个程序,通过调用某些方法向外部API发出请求。这些方法中的每一个都返回不同的JSON结构,它还取决于传递的参数。我的问题是,是否有某种方法可以使用Gson反序列化响应字符串,而无需为每个方法编写不同的类。
如果不是Gson,我可以使用哪个其他库?
谢谢。
答案 0 :(得分:4)
我的问题是,是否有某种方法可以使用Gson反序列化响应字符串,而无需为每个方法编写不同的类。
是的,有。如果您不关心反序列化为特定Java类型的JSON结构只是一个包含键值对的对象,其中所有值都是JSON基元,那么可以将结构简单地反序列化为{{1} }。
请注意,Map<String, String>
不起作用,因为它没有为Gson提供足够的类型信息来反序列化。 Gson只为每个值创建普通的Map<String, Object>
个实例 - 不是Object
或String
个实例,而只是普通的Integer
个实例。 JSON中的实际值不会反序列化。从表面上看,可以增强Gson以为Object
值创建更多特定于类型的实例,这似乎是合理的。例如,由于可以通过调用JsonPrimitive
来确定JsonPrimitive
是否为Boolean
,因此可能希望Gson只构建isBoolean()
,但它不会--Gson只会创建一个空的且可能无用的Boolean
。
这是一个证明这一点的例子。
input.json内容:
Object
<强> Foo.java:强>
{
"one":"won",
"too":22,
"3":false
}
此示例的输出为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}
的类型反序列化,则需要进行自定义反序列化处理。
如果JSON结构不是一组简单的键值对,其中值都是JSON基元,但包含像JSON对象这样的复杂类型的值,即使可以将所有值转换为{{ 1}},然后还需要实现自定义反序列化处理。
不要犹豫,转到the Gson Issues List并向适当特定的Java HashMap<String, Object>
类型提交改进的JSON原语反序列化的增强请求,或者提供一个简单的机制来转换任何值 - 包括复杂的JSON类型,如对象和数组 - 在Map中导入Strings
,这样就不需要上面描述的自定义反序列化处理。
答案 1 :(得分:1)
如果你想使用gson,你必须编写不同的类来表示来自不同方法的响应。如果响应是简单的键值,那么您可以将响应转换为HashMap<String,Object>
,它将充当“通用”类,以满足您的用例中的所有类型的响应。