(我想我理解这个问题涉及如何使用 Gson 将 JSON 映射结构反序列化为 Java Map
。)
Map
Gson 目前需要比原始问题中的 Java 类结构提供的更多类型信息。不要声明这randomDetails
是一个普通的 old Map
,而是让 Gson 知道它是一个Map<String, String>
. 然后,以下示例 JSON 和简单的反序列化代码按预期运行。
input.json 内容:
{
"handle":"the handle",
"random_details":{"one":1,"too":"B","3":false,"for":5.32}
}
Foo.java:
import java.io.FileReader;
import java.util.Map;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
public class Foo
{
public static void main(String[] args) throws Exception
{
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
Gson gson = gsonBuilder.create();
MyClass myObject = gson.fromJson(new FileReader("input.json"), MyClass.class);
System.out.println(gson.toJson(myObject));
}
}
class MyClass
{
@SerializedName("handle")
String nickName;
Map<String, String> randomDetails;
}
请注意,这会将 in 中的所有值转换Map
为Strings
. 如果你想要更通用的东西,比如 a Map<String, Object>
,或者如果randomDetails
必须是一个普通的旧的Map
没有额外的类型信息,那么有必要实现自定义反序列化处理,如用户指南中所述。String
(不幸的是,如果声明的 Java 类型是简单的,则Gson 目前不会自动从 JSON 基元生成 Java 值或基元类型Object
。因此,有必要实现自定义反序列化。)
这是一个这样的例子。
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.annotations.SerializedName;
public class Foo
{
public static void main(String[] args) throws Exception
{
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
gsonBuilder.registerTypeAdapter(MyClass.class, new MyClassDeserializer());
Gson gson = gsonBuilder.create();
MyClass myObject = gson.fromJson(new FileReader("input.json"), MyClass.class);
System.out.println(gson.toJson(myObject));
}
}
class MyClassDeserializer implements JsonDeserializer<MyClass>
{
@Override
public MyClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
JsonObject object = json.getAsJsonObject();
String nickName = object.get("handle").getAsString();
Set<Map.Entry<String, JsonElement>> mapEntries = object.get("random_details").getAsJsonObject().entrySet();
Map randomDetails = new HashMap(mapEntries.size());
for (Map.Entry<String, JsonElement> mapEntry : mapEntries)
{
String key = mapEntry.getKey();
Object value;
JsonPrimitive jsonPrimitive = mapEntry.getValue().getAsJsonPrimitive();
if (jsonPrimitive.isNumber()) value = jsonPrimitive.getAsNumber();
else if (jsonPrimitive.isBoolean()) value = jsonPrimitive.getAsBoolean();
else value = jsonPrimitive.getAsString();
randomDetails.put(key, value);
}
MyClass myObject = new MyClass();
myObject.nickName = nickName;
myObject.randomDetails = randomDetails;
return myObject;
}
}
class MyClass
{
@SerializedName("handle")
String nickName;
Map randomDetails;
}