Gson Adapter的用法

Gson Adapter的用法

使用了Gson库,别的不好说,感觉Adapter的设计模式和要处理的任务太贴合了,Gson提供了TypeAdapter接口,正好写一下处理的过程。

我遇到的情况相对还算比较麻烦,处理高德地图返回的Json,主要有三个问题

  1. 递归定义问题。districts里边有一个数组,里边是很多districts.
{
    "notcare1": "notcare1",
    "notcare2": "notcare2",
    "districts":[{
        "citycode": [],
        "adcode" : "adcode",
        "name" : "name",
        "notcare3": "notcare3",
        "districts":[
            "citycode": "citycode",
            "adcode" : "adcode",
            "name" : "name",
       	    "b" : "b"
        ] 
    },{
        "a": "a",
        "b" : "b",
        "districts":[
        
        ]
    }             
    ]
}

抽象写成Java类是这样的

public class Districts {
    String citycode;
    String adcode;
    String name;
    List<Districts> districtsList;
}
  1. 嵌套定义问题外层如上文所示,外层并不是一个distict,定义成Java类是这样的

    public class DistrictsFromAmap {
        List<Districts> districtsList;
    }
    
  2. 类型不确定问题。

​ citycode可能是个空数组,也可能是个字符串。好在我们希望处理后都是字符串

上文已经给出了针对上述问题实体怎么定义。Adapter怎么写?

首先处理递归问题。思想是,递归调用write(),read()。write直接遍历数组,read要创建数组再创建对象。

然后解决类型不确定问题。因为我就要String,只需要再in中处理即可。注意beginArray()和endArray()的配对问题。

package cn.aaronhu.cabinbackend.entity.districts;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.ArrayList;

public class DistrictTypeAdapter extends TypeAdapter<Districts> {
    private  final Gson gson;

    public DistrictTypeAdapter() {
        this.gson = new Gson();
    }

    @Override
    public void write(JsonWriter out, Districts districts) throws IOException {
        out.beginObject();
        out.name("citycode").value(districts.citycode);
        out.name("adcode").value(districts.adcode);
        out.name("name").value(districts.name);
        out.name("districts").beginArray();
        for (Districts childDistricts : districts.districtsList) {
            write(out,childDistricts);
        }
        out.endArray();
        out.endObject();
    }

    @Override
    public Districts read(JsonReader in) throws IOException {
        Districts districts = new Districts();
        in.beginObject();
        while(in.hasNext()){
            switch (in.nextName()){
                case "citycode":
                    switch (in.peek()){
                        case STRING:
                            districts.citycode = in.nextString();
                            break;
                        case BEGIN_ARRAY:
                            districts.citycode =  gson.fromJson(in,Object.class).toString();
                            break;
                        default:
                            throw new IllegalStateException("Unexpected" + in.peek());
                    }
                    break;
                case "adcode":
                    districts.adcode = in.nextString();
                    break;
                case "name":
                    districts.name = in.nextString();
                    break;
                case "districts":
                    districts.districtsList = new ArrayList<>();
                    in.beginArray();
                    while(in.hasNext()){
                        districts.districtsList.add(read(in));
                    }
                    in.endArray();
                    break;
                default:
                    in.skipValue();
                    break;
            }

        }
        in.endObject();
        return  districts;
    }
}

接下来解决嵌套定义问题

package cn.aaronhu.cabinbackend.entity.districts;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.ArrayList;

public class DistrictsFromAmapAdapter extends TypeAdapter<DistrictsFromAmap> {

    @Override
    public void write(JsonWriter out, DistrictsFromAmap districtsFromAmap) throws IOException {
        out.beginObject();
        out.name("districtList");
        out.beginArray();
        for(Districts districts: districtsFromAmap.getDistrictsList()) {
            new DistrictTypeAdapter().write(out,districts);
        }
        out.endArray();
        out.endObject();

    }

    @Override
    public DistrictsFromAmap read(JsonReader in) throws IOException {
        DistrictsFromAmap districtsFromAmap = new DistrictsFromAmap();
        in.beginObject();
        while (in.hasNext()){
            if ("districts".equals(in.nextName())) {
                districtsFromAmap.districtsList = new ArrayList<>();
                in.beginArray();
                while(in.hasNext()){
                    districtsFromAmap.districtsList.add(new DistrictTypeAdapter().read(in));
                }
                in.endArray();
            } else {
                in.skipValue();
            }
        }
        in.endObject();
        return districtsFromAmap;
    }
}

比较难受的是上来就是一个数组

常见错误分析:

JsonReader in 一个一个字段读,比如

{
    "a" : "b",
    "c" : "d"
}

比如我想读"a"后读"c",然后获取"d",要调用

[in.nextName(),in.skipValue(),in.nextName(),in.nextString()]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值