gson 怎么把空字符串去掉_Gson解析空字符串异常的处理

面对一些不规范的json,我们的gson解析经常会抛出各种异常导致app崩溃,这里可以采取一些措施来避免

11月9日更新:

关于数组类型的字段解析异常,我尝试了一些方案,但最后都存在问题,如果大家有好的解决方案,希望能贴在下面.不甚感激.

异常示例=>正常json:

{

"code":0,

"msg":"ok",

"data":[ //约定为数组

{

"id":5638,

"newsId":5638

}

]

}

异常json:

{

"code":0,

"msg":"ok",

"data":{} //返回为对象或者空字符串

}

Json异常情况

先来看一个后台返回的json

正常情况下json:

{

"code":0,

"msg":"ok",

"data":{

"id":5638,

"newsId":5638

}

}

data部分对应的实体类:

public class JsonBean {

private int id;

private int newsId;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public int getNewsId() {

return newsId;

}

public void setNewsId(int newsId) {

this.newsId = newsId;

}

}

异常情况json(后台数据库newsId字段未查询到对应数据):

{

"code":0,

"msg":"ok",

"data":{

"id":5638,

"newsId":""

}

}

这样Gson在解析时就会抛出解析错误的异常,app崩溃,原因是无法将""转化为int

json异常的处理

我们期望在后台返回的json异常时,也能解析成功,空值对应的转换为默认值,如:newsId=0;

这里排除掉后台开发人员输出时给你做矫正,还是得靠自己啊---

我们写一个针对int值的类型转换器,需要实现Gson的JsonSerializer接口和JsonDeserializer,即序列化和反序列化接口

public class IntegerDefault0Adapter implements JsonSerializer, JsonDeserializer {

@Override

public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)

throws JsonParseException {

try {

if (json.getAsString().equals("") || json.getAsString().equals("null")) {//定义为int类型,如果后台返回""或者null,则返回0

return 0;

}

} catch (Exception ignore) {

}

try {

return json.getAsInt();

} catch (NumberFormatException e) {

throw new JsonSyntaxException(e);

}

}

@Override

public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {

return new JsonPrimitive(src);

}

}

同理Long及Double类型

double=>

public class DoubleDefault0Adapter implements JsonSerializer, JsonDeserializer {

@Override

public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

try {

if (json.getAsString().equals("") || json.getAsString().equals("null")) {//定义为double类型,如果后台返回""或者null,则返回0.00

return 0.00;

}

} catch (Exception ignore) {

}

try {

return json.getAsDouble();

} catch (NumberFormatException e) {

throw new JsonSyntaxException(e);

}

}

@Override

public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {

return new JsonPrimitive(src);

}

}

long=>

public class LongDefault0Adapter implements JsonSerializer, JsonDeserializer {

@Override

public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)

throws JsonParseException {

try {

if (json.getAsString().equals("") || json.getAsString().equals("null")) {//定义为long类型,如果后台返回""或者null,则返回0

return 0l;

}

} catch (Exception ignore) {

}

try {

return json.getAsLong();

} catch (NumberFormatException e) {

throw new JsonSyntaxException(e);

}

}

@Override

public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {

return new JsonPrimitive(src);

}

}

所以使用是这样的:

return new Retrofit.Builder()

.client(okHttpClient)//设置网络访问框架

.addConverterFactory(GsonConverterFactory.create(buildGson()))//添加json转换框架

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//让Retrofit支持RxJava

.baseUrl(baseUrl)

.build();

/**

* 增加后台返回""和"null"的处理

* 1.int=>0

* 2.double=>0.00

* 3.long=>0L

*

* @return

*/

public static Gson buildGson() {

if (gson == null) {

gson = new GsonBuilder()

.registerTypeAdapter(Integer.class, new IntegerDefault0Adapter())

.registerTypeAdapter(int.class, new IntegerDefault0Adapter())

.registerTypeAdapter(Double.class, new DoubleDefault0Adapter())

.registerTypeAdapter(double.class, new DoubleDefault0Adapter())

.registerTypeAdapter(Long.class, new LongDefault0Adapter())

.registerTypeAdapter(long.class, new LongDefault0Adapter())

.create();

}

return gson;

}

再也不会因为后台json字段为空的情况崩溃了

关于作者

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值