如何使用GSON序列化地图的地图? [英] How to serialize a Map of a Map with GSON?

查看:109
本文介绍了如何使用GSON序列化地图的地图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to serialize my Example class below into JSON using GSON.

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无法序列化地图范围里面的地图一般。这是GSON的限制,还是我在这里做错了?

It seems that GSON cannot serialize the Map Range inside the Map General. Is this a limitation of GSON or am I doing something wrong here?

推荐答案

Nishant的答案的作品是因为Gson的默认构造函数支持所有类型的默认情况下,您将手动可以使用GsonBuilder的默认值。

The reason why Nishant's answer works is because Gson's default constructor enables all kind of stuff per default that you would otherwise have to manually enably using the GsonBuilder.

JavaDocs

构造具有默认配置的Gson对象。默认配置有以下设置:

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


  • 由toJson方法生成的JSON是紧凑的表示形式。这意味着所有不需要的空格被删除。您可以使用GsonBuilder.setPrettyPrinting()更改此行为。

  • 生成的JSON将忽略所有null的字段。请注意,数组中的空值保持原样,因为数组是有序列表。此外,如果一个字段不为空,但其生成的JSON为空,那么该字段将被保留。您可以通过设置GsonBuilder.serializeNulls()来配置Gson序列化空值。

  • Gson为Enums,Map,java.net.URL,java.net.URI提供了默认序列化和反序列化, java.util.Locale,java.util.Date,java.math.BigDecimal和java.math.BigInteger类。如果您希望更改默认表示形式,可以通过GsonBuilder.registerTypeAdapter(Type,Object)注册一个类型适配器来实现。

  • 默认的日期格式与java.text相同.DateFormat.DEFAULT。此格式将忽略序列化期间日期的毫秒部分。您可以通过调用GsonBuilder.setDateFormat(int)或GsonBuilder.setDateFormat(String)来更改此值。

  • 默认情况下,Gson将忽略com.google.gson.annotations.Expose注释。您可以通过GsonBuilder.excludeFieldsWithoutExposeAnnotation()来启用Gson序列化/反序列化标注此注释的字段。

  • 默认情况下,Gson忽略com.google.gson.annotations.Since注释。您可以启用Gson通过GsonBuilder.setVersion(double)使用此注释。

  • 输出Json的默认字段命名策略与Java中的相同。因此,Java类字段versionNumber将在Json中作为versionNumber @输出,同样的规则用于将传入的Json映射到Java类,您可以通过GsonBuilder.setFieldNamingPolicy(FieldNamingPolicy)更改此策略。

  • 默认情况下,Gson将序列化和反序列化的考虑中的瞬态或静态字段排除在外,您可以通过GsonBuilder.excludeFieldsWithModifiers(int)来更改此行为。

  • 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序列化器,如你所料,不支持嵌套的地图,如您在来自DefaultTypeAdapters的源代码片段(特别是如果您使用调试器浏览)变量 childGenericType 被设置为Som的类型 java.lang.Object 这是一个神秘的原因,所以从来没有分析过这个价值的运行时类型。


OK, now I see what the problem is. The default Map serializer, as you expected, does not support nested maps. As you can see in this source snippet from DefaultTypeAdapters (especially if you step through with a debugger) the variable childGenericType is set to the type java.lang.Object for some mysterious reason, so the runtime type of the value is never analysed.

两个解决方案,我猜:


  1. 实施您自己的地图序列化器/解串器

  2. 使用更复杂的方法,如下所示:

  1. Implement your own Map serializer / deserializer
  2. Use a more complicated version of your method, something like this:

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();
}


这篇关于如何使用GSON序列化地图的地图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆