Gson解析空字符串发生异常的处理方法
前言
在实际开发项目中,服务器经常会用空字符串“”作为返回结果表示空值,但这在Gson当中就会遇到问题,如果这项数据的类型不是字符串,Gson解析就会报错
Json异常情况
先来看一个后台返回的json
正常情况下json:
{
"code":0,
"msg":"ok",
"data":{
"id":5638,
"newsId":5638
}
}
data部分对应的实体类:
publicclassJsonBean{
privateintid;
privateintnewsId;
publicintgetId(){
returnid;
}
publicvoidsetId(intid){
this.id=id;
}
publicintgetNewsId(){
returnnewsId;
}
publicvoidsetNewsId(intnewsId){
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>,即序列化和反序列化接口
publicclassIntegerDefault0AdapterimplementsJsonSerializer<Integer>,JsonDeserializer<Integer>{
@Override
publicIntegerdeserialize(JsonElementjson,TypetypeOfT,JsonDeserializationContextcontext)
throwsJsonParseException{
try{
if(json.getAsString().equals("")||json.getAsString().equals("null")){//定义为int类型,如果后台返回""或者null,则返回0
return0;
}
}catch(Exceptionignore){
}
try{
returnjson.getAsInt();
}catch(NumberFormatExceptione){
thrownewJsonSyntaxException(e);
}
}
@Override
publicJsonElementserialize(Integersrc,TypetypeOfSrc,JsonSerializationContextcontext){
returnnewJsonPrimitive(src);
}
}
同理Long及Double类型
double=>
publicclassDoubleDefault0AdapterimplementsJsonSerializer<Double>,JsonDeserializer<Double>{
@Override
publicDoubledeserialize(JsonElementjson,TypetypeOfT,JsonDeserializationContextcontext)throwsJsonParseException{
try{
if(json.getAsString().equals("")||json.getAsString().equals("null")){//定义为double类型,如果后台返回""或者null,则返回0.00
return0.00;
}
}catch(Exceptionignore){
}
try{
returnjson.getAsDouble();
}catch(NumberFormatExceptione){
thrownewJsonSyntaxException(e);
}
}
@Override
publicJsonElementserialize(Doublesrc,TypetypeOfSrc,JsonSerializationContextcontext){
returnnewJsonPrimitive(src);
}
}
long=>
publicclassLongDefault0AdapterimplementsJsonSerializer<Long>,JsonDeserializer<Long>{
@Override
publicLongdeserialize(JsonElementjson,TypetypeOfT,JsonDeserializationContextcontext)
throwsJsonParseException{
try{
if(json.getAsString().equals("")||json.getAsString().equals("null")){//定义为long类型,如果后台返回""或者null,则返回0
return0l;
}
}catch(Exceptionignore){
}
try{
returnjson.getAsLong();
}catch(NumberFormatExceptione){
thrownewJsonSyntaxException(e);
}
}
@Override
publicJsonElementserialize(Longsrc,TypetypeOfSrc,JsonSerializationContextcontext){
returnnewJsonPrimitive(src);
}
}
所以使用是这样的:
returnnewRetrofit.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
*/
publicstaticGsonbuildGson(){
if(gson==null){
gson=newGsonBuilder()
.registerTypeAdapter(Integer.class,newIntegerDefault0Adapter())
.registerTypeAdapter(int.class,newIntegerDefault0Adapter())
.registerTypeAdapter(Double.class,newDoubleDefault0Adapter())
.registerTypeAdapter(double.class,newDoubleDefault0Adapter())
.registerTypeAdapter(Long.class,newLongDefault0Adapter())
.registerTypeAdapter(long.class,newLongDefault0Adapter())
.create();
}
returngson;
}
再也不会因为后台json字段为空的情况崩溃了
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能有所帮助,如果有疑问大家可以留言交流。