一尘不染

如何在反序列化JSON响应中使用Gson处理NumberFormatException

json

我正在读取Gson的JSON响应,该响应返回somtimes
a,NumberFormatException因为期望值int设置为空字符串。现在,我想知道处理这种异常的最佳方法是什么。如果该值为空字符串,则反序列化应为0。

预期的JSON响应:

{
   "name" : "Test1",
   "runtime" : 90
}

但是有时运行时是一个空字符串:

{
   "name" : "Test2",
   "runtime" : ""
}

java类如下所示:

public class Foo
{
    private String name;
    private int runtime;
}

反序列化是这样的:

String input = "{\n" +
               "   \"name\" : \"Test\",\n" +
               "   \"runtime\" : \"\"\n" +
               "}";

Gson gson = new Gson();
Foo foo = gson.fromJson(input, Foo.class);

com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String因为返回一个空String而不是一个int值,所以抛出a 。

有没有办法告诉Gson:“ 如果反序列化runtimeType
的字段Foo并且存在NumberFormatException,则只需返回默认值0
”即可?

我的解决方法是使用a String作为runtime字段的Type 而不是int,但是也许有更好的方法来处理此类错误。


阅读 618

收藏
2020-07-27

共1个答案

一尘不染

最初,我尝试为Integer值编写一个通用的自定义类型适配器,以捕获NumberFormatException和返回0,但Gson不允许基本类型的TypeAdaptors:

java.lang.IllegalArgumentException: Cannot register type adapters for class java.lang.Integer

之后,我FooRuntime为该runtime字段引入了一个新的Type ,因此Foo该类现在如下所示:

public class Foo
{
    private String name;
    private FooRuntime runtime;

    public int getRuntime()
    {
        return runtime.getValue();
    }
}

public class FooRuntime
{
    private int value;

    public FooRuntime(int runtime)
    {
        this.value = runtime;
    }

    public int getValue()
    {
        return value;
    }
}

类型适配器处理自定义反序列化过程:

public class FooRuntimeTypeAdapter implements JsonDeserializer<FooRuntime>, JsonSerializer<FooRuntime>
{
    public FooRuntime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
    {
        int runtime;
        try
        {
            runtime = json.getAsInt();
        }
        catch (NumberFormatException e)
        {
            runtime = 0;
        }
        return new FooRuntime(runtime);
    }

    public JsonElement serialize(FooRuntime src, Type typeOfSrc, JsonSerializationContext context)
    {
        return new JsonPrimitive(src.getValue());
    }
}

现在必须使用GsonBuilder注册类型适配器,因此将空字符串解释为0而不是抛出NumberFormatException

String input = "{\n" +
               "   \"name\" : \"Test\",\n" +
               "   \"runtime\" : \"\"\n" +
               "}";

GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(FooRuntime.class, new FooRuntimeTypeAdapter());
Gson gson = builder.create();
Foo foo = gson.fromJson(input, Foo.class);
2020-07-27