如何在反序列化中使用Gson处理NumberFormatException JSON响应 [英] How to handle a NumberFormatException with Gson in deserialization a JSON response

查看:2111
本文介绍了如何在反序列化中使用Gson处理NumberFormatException JSON响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Gson 阅读JSON响应,该响应时间仅为 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 \,\\\
+
\runtime \:\\\\\
+
};

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

抛出 com.google.gson.JsonSyntaxException:java.lang。 NumberFormatException:空字符串,因为返回空字符串而不是int值。



有没有办法告诉Gson,如果你反序列化类型为 runtime 的字段 Foo 并且有一个NumberFormatException,只返回默认值0 ?



我的解决方法是使用 String 作为运行时字段的类型,而不是 int ,但也许有更好的方法来处理这样的错误。

解决方案

起初,我试图写一个一般的自定义键入适配器的Integer值,以捕获 NumberFormatException 并返回0,但Gson不允许TypeAdaptors用于原始类型:

  java.lang.IllegalArgumentException:无法注册类java.lang.Integer的类型适配器

之后,我为运行时字段引入了一个新的Type FooRuntime ,所以 Foo class现在看起来像这样:

  public class Foo 
{
私人字符串名称;
私人FooRuntime运行时;

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

public class FooRuntime
{
private int value;

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

public int getValue()
{
返回值;






$ b

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

  public class FooRuntimeTypeAdapter实现了JsonDeserializer< FooRuntime>,JsonSerializer< FooRuntime> 
{
public FooRuntime反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext上下文)throws JsonParseException
{
int runtime;
尝试
{
runtime = json.getAsInt();

catch(NumberFormatException e)
{
runtime = 0;
}
返回新的FooRuntime(运行时);
}

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


$ / code $ / pre

现在有必要使用 GsonBuilder 来注册类型适配器,所以一个空字符串被解释为0而不是抛出 NumberFormatException

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

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


I'm reading a JSON response with Gson, which returns somtimes a NumberFormatException because an expected int value is set to an empty string. Now I'm wondering what's the best way to handle this kind of exception. If the value is an empty string, the deserialization should be 0.

Expected JSON response:

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

But sometimes the runtime is an empty string:

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

The java class looks like this:

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

And the deserialization is this:

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

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

Which throws a com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String because an empty String is returned instead of an int value.

Is there a way to tell Gson, "if you deserialize the field runtime of the Type Foo and there is a NumberFormatException, just return the default value 0"?

My workaround is to use a String as the Type of the runtime field instead of int, but maybe there is a better way to handle such errors.

解决方案

At first, I tried to write a general custom type adaptor for Integer values, to catch the NumberFormatException and return 0, but Gson doesn't allow TypeAdaptors for primitive Types:

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

After that I introduced a new Type FooRuntime for the runtime field, so the Foo class now looks like this:

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

A type adaptor handles the custom deserialization process:

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

Now it's necessary to use GsonBuilder to register the type adapter, so an empty string is interpreted as 0 instead of throwing a 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);

这篇关于如何在反序列化中使用Gson处理NumberFormatException JSON响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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