【问题标题】:How to perform custom serialization in Gson using JsonElement?如何使用 JsonElement 在 Gson 中执行自定义序列化?
【发布时间】:2019-03-01 23:38:12
【问题描述】:

我使用 gson 来序列化和反序列化 java 对象以及它的内置 JsonElement。如果我正在序列化一个 java 对象,那么我可以注册一个类型适配器,它将被调用并允许我提供自定义序列化。

但是当我有一个 JsonElement 时,我似乎无法让它识别我想要适应的类型。说我有这个:

JsonArray arr = new JsonArray();
arr.add(Math.PI);
arr.add(Math.E);
System.out.println(arr.toString());

这将打印出来:

[3.141592653589793,2.718281828459045]

但是我如何将其限制为三个小数位?我希望我可以添加一个类型适配器,但我无法注册任何东西,即永远不会调用适配器的方法。在这种情况下,我应该注册一个 Double、Number、JsonPrimitive 还是其他东西?我都试过了,没有任何效果。

即使它确实有效,我认为我能做的最好的就是一些数学四舍五入,因为如果我尝试使用 String.format() 来“调整”数字,那么结果将是一个字符串而不是一个数字,并且我希望输出 json 保持为数字。

或者也许我完全错过了什么?这是我尝试过的一个示例:

Gson gson = (new GsonBuilder()).registerTypeAdapter(
    JsonPrimitive.class,
    new TypeAdapter<JsonPrimitive>() {
        @Override
        public JsonPrimitive read(JsonReader reader) throws IOException {
            // never using deserialization, don't expect this to print
            System.out.println("read adapter");
            return null;
        }

        @Override
        public void write(JsonWriter writer, JsonPrimitive primitive) throws IOException {
            // this never gets called; output same as above
            System.out.println("write adapter");
            writer.nullValue();
        }
    }
).create();
System.out.println(gson.toJson(arr));

【问题讨论】:

    标签: java gson deserialization


    【解决方案1】:

    我们无法更改 Json* 类的内部适配器,因为 Gson 使用预定义的 com.google.gson.internal.bind.TypeAdapters.JSON_ELEMENT。但幸运的是,我们可以提供我们的JsonWriter 实现。覆盖您需要的方法并将您的实现提供给序列化过程。例如,要舍入双打,请使用BigDecimal。自定义实现示例:

    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import com.google.gson.JsonArray;
    import com.google.gson.stream.JsonWriter;
    
    import java.io.IOException;
    import java.io.StringWriter;
    import java.math.BigDecimal;
    
    public class GsonApp {
    
        public static void main(String[] args) {
            Gson gson = new GsonBuilder().create();
            JsonArray array = new JsonArray();
            array.add(Math.PI);
            array.add(Math.E);
    
            StringWriter stringWriter = new StringWriter();
            JsonWriter jsonWriter = new JsonWriter(stringWriter) {
                @Override
                public JsonWriter value(Number value) throws IOException {
                    BigDecimal bigDecimal = BigDecimal.valueOf(value.doubleValue());
                    BigDecimal result = bigDecimal.setScale(3, BigDecimal.ROUND_UP);
    
                    return super.value(result.doubleValue());
                }
            };
            jsonWriter.setIndent("  ");
    
            gson.toJson(array, jsonWriter);
            System.out.println(stringWriter.toString());
        }
    }
    

    上面的代码打印:

    [
      3.142,
      2.719
    ]
    

    另见:

    【讨论】:

    • 完美,谢谢,这正是我一直在寻找的,而且我自己永远也想不出来。干杯!
    猜你喜欢
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    相关资源
    最近更新 更多