Gson-特殊的Double和Float字段的处理-serializeSpecialFloatingPointValues

    xiaoxiao2022-07-13  149

    serializeSpecialFloatingPointValues Java语言中Float Double类中有一些自定义的类型例如

    public static final double NaN = 0.0d / 0.0; public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308

    这些并不是规范的JSON里的,正常情况下会报异常:

    Exception in thread "main" java.lang.IllegalArgumentException: NaN is not a valid double value as per JSON specification. To override this behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method. at com.google.gson.Gson.checkValidFloatingPoint(Gson.java:359) at com.google.gson.Gson$2.write(Gson.java:351) at com.google.gson.Gson$2.write(Gson.java:337) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245) at com.google.gson.Gson.toJson(Gson.java:704) at com.google.gson.Gson.toJson(Gson.java:683) at com.google.gson.Gson.toJson(Gson.java:638) at com.google.gson.Gson.toJson(Gson.java:618) at com.company.util.GsonUtil.testSerializeSpecialFloatingPointValues(GsonUtil.java:42) at com.company.util.GsonUtil.main(GsonUtil.java:35)

    测试代码:

    static Gson sGson; static Gson getGson() { if (sGson == null) { sGson = getGsonBuilder().create(); } return sGson; } private static GsonBuilder getGsonBuilder() { return new GsonBuilder().setDateFormat( "yyyy年MM月dd日 HH时mm分ss秒").disableHtmlEscaping().serializeNulls().enableComplexMapKeySerialization().setLenient(); } public static void main(String[] args) { testSerializeSpecialFloatingPointValues(); } private static void testSerializeSpecialFloatingPointValues() { Empolyee empolyee = new Empolyee("longxia", Float.NaN, Double.POSITIVE_INFINITY); String result = getGson().toJson(empolyee); System.out.println(result); } static class Empolyee { String name; float department; Double score; public Empolyee(String name, float department, Double score) { this.name = name; this.department = department; this.score = score; } }

    反序列化是否有问题呢?

    private static void testSerializeSpecialFloatingPointValues() { String result = "{\"name\":\"longxia\",\"department\":NaN,\"score\":Infinity}"; System.out.println(result); Empolyee empolyee = getGson().fromJson(result,Empolyee.class); System.out.println(empolyee.name+" "+empolyee.department+" "+empolyee.score); }

    输出结果:

    {"name":"longxia","department":NaN,"score":Infinity} longxia NaN Infinity

    所以谁否设置该属性并不会影响反序列化,只是会影响序列化的过程,现在加上改方法:

    private static GsonBuilder getGsonBuilder() { return new GsonBuilder().setDateFormat( "yyyy年MM月dd日 HH时mm分ss秒").serializeSpecialFloatingPointValues().disableHtmlEscaping().serializeNulls().enableComplexMapKeySerialization().setLenient(); }

    序列化结果为

    {"name":"longxia","department":NaN,"score":Infinity}

    总结:serializeSpecialFloatingPointValues方法只会影响序列化结果,不会影响反序列的结果,默认情况下,序列化不能序列非json规范中的flot,double中的一些字段,但是配置该方法后,既可以序列化这些不规范的字段。当然还是建议不要在代码中适用这些字段。

    最新回复(0)