在前面的这篇文章中Android开发的5个神器中,推荐了Retrofi库,这是一个网络请求库,默认是使用Gson解析JSON数据。
Gson解析JSON数据,默认是把JSON的字段名和java对象的变量对应。如果不一样,可以用Annotation声明对应的JSON字段名,如下:
public class User {
@SerializedName("userid")
public String uid;
@SerializedName("username")
public String name;
}
对应的Json就是这样的:
{
"userid": 123;
"username": "Jack"
}
还有一些控制Java对象中的成员是否需要序列化的方法。
* transient
关键字,可以控制不进行序列化和反序列化JSON
* @Expose
可以精细控制序列化和反序列化
public class Account {
@Expose(deserialize = false)
private String accountNumber;
@Expose
private String iban;
@Expose(serialize = false)
private String owner;
@Expose(serialize = false, deserialize = false)
private String address;
private String pin;
}
配置使用了@Expose
标签,需要显式配置Gson,如下:
final GsonBuilder builder = new GsonBuilder();
builder.excludeFieldsWithoutExposeAnnotation();
final Gson gson = builder.create();
详情可以参考这里GSON ANNOTATIONS EXAMPLE。
另外,很多服务器返回的JSON的数据中,经常会包含一些通用的状态信息,然后把真正的数据放在一个子JSON中,如下:
{
'status': 'OK',
'reason': 'Everything was fine',
'content': {
< some data here >
}
}
真正的内容在'content'
字段中,解决的方法,自定义一个JsonDeserializer
,如下:
class MyDeserializer<T> implements JsonDeserializer<T>
{
@Override
public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
// Get the "content" element from the parsed JSON
JsonElement content = je.getAsJsonObject().get("content");
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(content, type);
}
}
使用的时候如下:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Content.class, new MyDeserializer<Content>())
.registerTypeAdapter(DiffContent.class, new MyDeserializer<DiffContent>())
.build();
解决方法参考自StackOverflow。