其实本来没有打算写这个调调的,但是,谁知道呢。
市面上常用的解析json 的工具还是蛮多的。因为as 有一个 gsonfomat ,感觉再去用其他的,感觉有点不好意思,谁知道呢,反正就用gson 了。
废话就不多说了,现在一般情况下,服务器接口都是返回的json 格式。通常来说 服务器 返回的数据 会在最外面包装一层数据,使得真正有用的数据是一个内部类。大概长这个样子。
{
"code": 1,
"data": {},
"msg": ""
}
data 就是 我们要求的数据,code 是服务器定义的错误码,msg 就是信息。嗯嗯,大致就是这样样子了。因为有的数据里面data 是对象,有的是数组。所以这个 需要在自己定义entity 的时候 自己 注意就好了,这个还是看后台的。比如现在的后台对数字是包裹了一层的。像这个样子。
{
"code": 1,
"data": {
"nowPage": 1,
"list": [],
"totalPage": 2,
"hasNextPage": true,
"totalSize": 13,
"signNewNums": 0,
"nums": 0
},
"msg": "操作成功"
}
list 才是 需要的数据。但是 无论如何,最外层的
{ "code": 1,"data": {},"msg": ""}
是相同的,所以 第一时间 能够想到的是泛型。
image.png
image.png
通过 泛型T 将内部类传递进去解析。这么 我们建立entity 的时候就只需要 创建不同的地方了。使用 大概 就是 :
image.png
但是,可能就不是Retrofit。如果 直接 通过 gson class 解析 可能会出问题,我也忘了 是解析 数组还是对象出的问题了。这个时候就需要一个 TypeToken,大概是这样用的, image.png
泛型也可以这么用。这个TypeToken 的扩展就多的去了,这个可以解析解析 list,map ,set 之类的(set我没有用过,但是应该没有问题)
上面的都是一些很基础很常用的东西。
现在说一点不常用的。
有些时候,和服务器端的大佬 默契度不够的时候,本地控制逻辑的entity 和服务器返回的entity 不一样的时候,又需要使用服务器返回的数据的时候,就可以考虑采用 @SerializedName("cc_json") ,用于设置字段别名。好像同一个值是可以设置多个别名的。大概这么使用。
image.png
当然默契度太低的时候,建议手动new 对象 赋值。
还有一种情况,本地填写的数据,要使用json 通过表达提交 给服务器。但是呢,本地定义的entity 里面有一些多余的字段或者原始字段怎么办呢,服务器又要求你不上传这些给他,解决办法很多,1个就是新建一个对象 赋值然后转json,还有一个就是通过gson 忽略字段了。@Expose 只有该对象上注解了 这个的才会打印出来。当然 这个需要 在gson create 之前开启 Expose 才可以使用。比如这样:
public class GsonHelper {
private final Gson gson;
public GsonHelper() {
gson = new GsonBuilder()
.setLenient()// json宽松
.enableComplexMapKeySerialization()//支持Map的key为复杂对象的形式
.serializeNulls() //智能null
.setPrettyPrinting()// 调整格式 ,使对齐
.disableHtmlEscaping() //默认是GSON把HTML 转义的
//.setExclusionStrategies(excludeStrings) //自定义排除转json的字段或者类名
.excludeFieldsWithoutExposeAnnotation()//启用 @Expose
.create();
}
public String toJson(Object object){
return gson.toJson(object);
}
}
使用:就是new GsonHelper().tojson(T);T 是传入的对象。
但是呢,有的时候,同一个对象 忽略的字段在不同的功能上 是不同的,就需要涉及到动态忽略了。
和上面差不多,同样是 需要在gson create 之前进行设置。
Gson gson=new GsonBuilder().setExclusionStrategies(new CurrencyExpose(ExposeDataUtils.getHospitalDepartments())).create();
主要是 setExclusionStrategies();
/**
* 通用 忽略字段。
*/
public class CurrencyExpose implements ExclusionStrategy {
List<String> keys=new ArrayList<>();
public CurrencyExpose(List<String> keys) {
this.keys.clear();
this.keys.addAll(keys);
}
@Override
public boolean shouldSkipField(FieldAttributes f) {
return keys.contains(f.getName());
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
}
ExposeDataUtils.getHospitalDepartments()主要是获取 忽略的字段的字段名。
其他类似 扩展 由于我也没有用过,所以,请百度下 ExclusionStrategy吧。
好了,大概就是这些了,如有错误,欢迎指正,谢谢了。
网友评论