json类型转换

前言
在日常开发中,我们经常会用到json转对象,或者对象转json的情况,一般用到的就是阿里的Fastjson和谷歌的Gson。
本篇要说的是Gson中如何将json数据转换为我们想要的数据类型。
1.json直接转对象
我们一般的操作姿势:
直接复制后台下发的json,然后在Android Studio使用Gson插件快捷生成实体类:
但是呢,有时候
这块是一个模版json,我们在对数据做处理的时候,希望让data给调用者自己去处理。通过传入一个Class类型,来自动把我们data里面的字符串解析成对应的Class对象。
2.泛型化data数据体
public class ApiResultBean<T> {
/**
* msg : 获取成功!
* code : 200
* data : {}
*/
private String msg;
private int code;
private T data;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
这样,我们可以把json中,我们需要处理的对象解析为 T类型。
然后在解析服务器返回的json时,我们可以直接通过Gson进行解析:
ApiResultBean responseState = new Gson().fromJson(json, type);
我们看到,在进行解析时,需要传入一个类型,例如:我们的T类型是一个Movie电影列表信息,则可以这样写:
new TypeToken<ApiResultBean<List<MovieBean>>>(){}.getType();
这里的T = List<MovieBean>,这样我们的数据就能正常处理成功了。
如果是一个字符串类型则是T = String
new TypeToken<ApiResultBean<String>>(){}.getType();
但是,使用这种方式的前提是,我们在调用后台API的时候,明确知道,返回的T类型,而且类型是不变的。
例如,后台在做后台推送时,我们不知道后台推送的json数据返回的data数据体是哪种T类型,这个时候,这种方式就无法使用了。
3.Gson类型适配器
我们知道gson是可以自定义json类型解析的,实现方法如下:
public class ApiGsonBuilder {
private static final GsonBuilder INSTANCE = new GsonBuilder();
static {
INSTANCE.disableHtmlEscaping();
INSTANCE.registerTypeAdapter(MqttBaseMsgBean.class, new MqttMsgAdapter());
}
public static Gson create() {
return INSTANCE.create();
}
}
第一步:禁用Html转义;
第二步:注册类型adapter,传入我们的json实体类,和解析规则;
第三步:使用自定义的gson对json数据进行解析;
下面看下我们的type adapter,以 MqttBaseMsgBean 为例。
MqttBaseMsgBean 主要是根据下发的不同的cmd字符串,来判断需要传入的T类型:
public class MqttBaseMsgBean implements Serializable {
/**
* id :
* ts : 323123213213
* nonce : xxx
* sign : xxx
* cmd : reboot
* data : {"code":"200","msg":"success"}
*/
private String id;
private String ts;
private String nonce;
private String sign;
private String cmd;
private String data;
public MqttBaseMsgBean() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTTs() {
return ts;
}
public void setTTs(String ts) {
this.ts = ts;
}
public String getNonce() {
return nonce;
}
public void setNonce(String nonce) {
this.nonce = nonce;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public String getData() {
if (data == null) {
return "{}";
}
return data;
}
public void setData(String data) {
this.data = data;
}
}
我们看到data : {"code":"200","msg":"success"},是一个object对象,但是我们把它转换成了String类型,这个时候,我们就可以拿到这个String data,然后在对这个字符串进行解析了,只是比上面传入T类型的方式多了一步类型转换。
那么,我们的MqttMsgAdapter.java,是怎么解析的呢?
public class MqttMsgAdapter implements JsonDeserializer<MqttBaseMsgBean> {
public MqttBaseMsgBean deserialize(JsonElement json, Type type,
JsonDeserializationContext context)
throws JsonParseException {
MqttBaseMsgBean result = new MqttBaseMsgBean();
JsonObject jsonObject = json.getAsJsonObject();
JsonElement ret;
ret = jsonObject.get("id");
if (ret != null && !ret.isJsonNull()) {
result.setId(GsonHelper.getAsString(ret));
}
ret = jsonObject.get("ts");
if (ret != null && !ret.isJsonNull()) {
result.setTTs(GsonHelper.getAsString(ret));
}
ret = jsonObject.get("nonce");
if (ret != null && !ret.isJsonNull()) {
result.setNonce(GsonHelper.getAsString(ret));
}
ret = jsonObject.get("sign");
if (ret != null && !ret.isJsonNull()) {
result.setSign(GsonHelper.getAsString(ret));
}
ret = jsonObject.get("cmd");
if (ret != null && !ret.isJsonNull()) {
result.setCmd(GsonHelper.getAsString(ret));
}
ret = jsonObject.get("data");
if (ret != null && !ret.isJsonNull()) {
result.setData(ret.toString());
}
return result;
}
}
看到这里,我们一下就清楚了,我们把所有的字段都解析成了JsonElement,然后根据需求,将jsonElement转换成我们需要的类型即可,如:
ret = jsonObject.get("data");
if (ret != null && !ret.isJsonNull()) {
result.setData(ret.toString());
}
这样,我们就将data这个object类型转换成了String类型,这样第一次Gson解析就完成了。
当我们拿到cmd命令后,根据不同的cmd,就可以对String data 进行不同的转换了:
MqttBaseMsgBean bodyBean = ApiGsonBuilder.create().fromJson(json, MqttBaseMsgBean.class);
if (bodyBean != null && !TextUtils.isEmpty(bodyBean.getCmd())) {
if (bodyBean.getCmd().equalsIgnoreCase("reboot")) {
ShellUtil.execShellReboot();
} else if (bodyBean.getCmd().equalsIgnoreCase("powerOff")) {
ShellUtil.execShellShutDown();
} else if (bodyBean.getCmd().equalsIgnoreCase("uploadLog")) {
MqttLogBean logBean = ApiGsonBuilder.create().fromJson(bodyBean.getData(), MqttLogBean.class);
if (logBean != null) {
uploadLog(context, bodyBean.getId(), logBean);
}
}
}
上面的代码中,我们将json转换成了MqttBaseMsgBean对象,然后判断cmd命令是reboot,还是powerOff,还是updataLog?三种类型的命令,来判断我们需要把data字符串,是解析成MqttLogBean,还是直接执行关机或重启动作。
这样就完成了整个json数据的解析。
当然,你也可以使用FastJson来解析json数据,各有优势吧。




更多推荐
所有评论(0)