如何使用JsonElement在Gson中执行自定义序列化?

时间:2019-03-01 23:38:13

标签: java gson deserialization

我使用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));

1 个答案:

答案 0 :(得分: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
]

另请参阅: