欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Gson解析空字符串发生异常的处理方法

程序员文章站 2024-03-12 15:11:32
前言 在实际开发项目中,服务器经常会用空字符串 “” 作为返回结果表示空值 ,但这在gson当中就会遇到问题,如果这项数据的类型不是字符串,gson解析就会报错 jso...

前言

在实际开发项目中,服务器经常会用空字符串 “” 作为返回结果表示空值 ,但这在gson当中就会遇到问题,如果这项数据的类型不是字符串,gson解析就会报错

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<t> 接口和 jsondeserializer<t> ,即序列化和反序列化接口

public class integerdefault0adapter implements jsonserializer<integer>, jsondeserializer<integer> {
 @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<double>, jsondeserializer<double> {
 @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<long>, jsondeserializer<long> {
 @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字段为空的情况崩溃了

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能有所帮助,如果有疑问大家可以留言交流。