.
有时候需要对 Json 中的某些字段保持原样,不进行解析。
那么可以使用 JsonElement 类型,例如:
Json 数据:
{
"id": 837,
"name": "input_text",
"extras": {
"language": "en-us",
"enable": false,
"text": "life is hard",
"voice": "ivy",
"format": "wav",
"sr": 24000
}
}
数据实体:
public class Data {
@SerializedName("id")
public int id;
@SerializedName("name")
public String name;
//附加字段,客户端不需要关心,透传给服务端接口
@SerializedName("extras")
public JsonElement extras;
}
但是,如果上面的 Data 实现了 Serializable 接口的话,则在进行序列化(反序列化)时,会抛出异常,原因是 JsonElement 不支持序列化。
下面给出一种解决方法:
public class Data implements Serializable {
@SerializedName("id")
public int id;
@SerializedName("name")
public String name;
/**
* 附加字段,客户端不需要关心,透传给服务端接口
*
* 1. extra内容客户端不关心,不进行解析,所以用JsonElement存放
* 2. 由于JsonElement没有实现Serializable,所以要加transient关键字
* 3. 但是加了transient会导致Gson忽略该字段,使得extras=null
* 4. 最后通过自定义Adapter的方法来解决,用String来存储未解析的内容
*/
@SerializedName("extras")
@JsonAdapter(RawStringJsonAdapter.class)
public String extras;
}
上面通过 @JsonAdapter 注解给 extras 绑定了一个 RawStringJsonAdapter,它的代码如下:
//将部分json内容保留为字符串形式,不进行解析
public static class RawStringJsonAdapter extends TypeAdapter<String> {
@Override
public void write(JsonWriter out, String value) throws IOException {
out.jsonValue(value);
}
@Override
public String read(JsonReader in) throws IOException {
return new JsonParser().parse(in).toString();
}
}
这样一来,我们就可以把那些不想解析的 Json 内容存储到 String 中,解决了 JsonElement 不能序列化的问题。
.