gpt4 book ai didi

java - 如何使用 GSON 序列化 map 的 map ?

转载 作者:搜寻专家 更新时间:2023-10-30 21:27:08 27 4
gpt4 key购买 nike

我想使用 GSON 将下面的示例类序列化为 JSON。

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.LinkedHashMap;

public class Example
{
private LinkedHashMap<String,Object> General;

private static final String VERSION="Version";
private static final String RANGE="Range";
private static final String START_TIME="Start_Time";
private static final String END_TIME="End_Time";

public Example() {
General = new LinkedHashMap<String,Object>();
General.put(VERSION, "0.1");

LinkedHashMap<String,String> Range = new LinkedHashMap<String, String>();
Range.put(START_TIME, "now");
Range.put(END_TIME, "never");

General.put(RANGE, Range);
}

public String toJSON() {
Gson gson = new GsonBuilder().serializeNulls().create();
return gson.toJson(this);
}
}

我希望得到以下输出:

{"General":{"Version":"0.1","Range":{"Start_Time":"now","End_Time":"never"}}}

但是调用函数 toJSON() 返回

{"General":{"Version":"0.1","Range":{}}}

看来 GSON 无法序列化 Map General 中的 Map Range。这是 GSON 的限制还是我在这里做错了什么?

最佳答案

为什么Nishant's answer的原因之所以有效,是因为 Gson 的默认构造函数默认启用了所有类型的东西,否则您必须使用 GsonBuilder 手动启用。

来自JavaDocs :

Constructs a Gson object with default configuration. The default configuration has the following settings:

  • The JSON generated by toJson methods is in compact representation. This means that all the unneeded white-space is removed. You can change this behavior with GsonBuilder.setPrettyPrinting().
  • The generated JSON omits all the fields that are null. Note that nulls in arrays are kept as is since an array is an ordered list. Moreover, if a field is not null, but its generated JSON is empty, the field is kept. You can configure Gson to serialize null values by setting GsonBuilder.serializeNulls().
  • Gson provides default serialization and deserialization for Enums, Map, java.net.URL, java.net.URI, java.util.Locale, java.util.Date, java.math.BigDecimal, and java.math.BigInteger classes. If you would prefer to change the default representation, you can do so by registering a type adapter through GsonBuilder.registerTypeAdapter(Type, Object).
  • The default Date format is same as java.text.DateFormat.DEFAULT. This format ignores the millisecond portion of the date during serialization. You can change this by invoking GsonBuilder.setDateFormat(int) or GsonBuilder.setDateFormat(String).
  • By default, Gson ignores the com.google.gson.annotations.Expose annotation. You can enable Gson to serialize/deserialize only those fields marked with this annotation through GsonBuilder.excludeFieldsWithoutExposeAnnotation().
  • By default, Gson ignores the com.google.gson.annotations.Since annotation. You can enable Gson to use this annotation through GsonBuilder.setVersion(double).
  • The default field naming policy for the output Json is same as in Java. So, a Java class field versionNumber will be output as "versionNumber@quot; in Json. The same rules are applied for mapping incoming Json to the Java classes. You can change this policy through GsonBuilder.setFieldNamingPolicy(FieldNamingPolicy).
  • By default, Gson excludes transient or static fields from consideration for serialization and deserialization. You can change this behavior through GsonBuilder.excludeFieldsWithModifiers(int).

好的,现在我知道问题出在哪里了。如您所料,默认的 Map 序列化程序不支持嵌套映射。正如您在 this source snippet from DefaultTypeAdapters 中看到的那样(特别是如果你使用调试器单步执行)变量 childGenericType 出于某种神秘的原因被设置为 java.lang.Object 类型,因此值的运行时类型是从未分析过。

我猜有两种解决方案:

  1. Implement your own Map serializer / deserializer
  2. 使用您的方法的更复杂版本,如下所示:

    public String toJSON(){
    final Gson gson = new Gson();
    final JsonElement jsonTree = gson.toJsonTree(General, Map.class);
    final JsonObject jsonObject = new JsonObject();
    jsonObject.add("General", jsonTree);
    return jsonObject.toString();
    }

关于java - 如何使用 GSON 序列化 map 的 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4547739/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com