参考(不限于):http://www.jianshu.com/p/e740196225a4
1.使用@SerializedName,处理客户端与服务端字段明命名不一致
@SerializedName(value = "emailAddress", alternate = {"email", "email_address"})
public String emailAddress;
2.使用TypeToken,处理泛型擦除
//方法声明
public T fromJson(String json, Class classOfT) throws JsonSyntaxException { Object object = fromJson(json, (Type) classOfT); return Primitives.wrap(classOfT).cast(object);}
Gson gson = new Gson();
String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";
String[] strings = gson.fromJson(jsonArray, String[].class);
//错误写法
List strings =gson.fromJson(jsonArray, String[].class);
//正确写法
List stringList = gson.fromJson(jsonArray, new TypeToken>() {}.getType());
3.使用泛型,改善POJO的设计
//原设计
public class UserResult {
public int code;
public String message;
public User data;
}
public class UserListResult {
public int code;
public String message;
public List data;
}
String json = "{..........}";
Gson gson = new Gson();
UserResult userResult = gson.fromJson(json,UserResult.class);
User user = userResult.data;UserListResult userListResult = gson.fromJson(json,UserListResult.class);
List users = userListResult.data;
//新设计
public class Result {
public int code;
public String message;
public T data;
}
Type userType = new TypeToken>(){}.getType();
Result userResult = gson.fromJson(json,userType);User user = userResult.data;
Type userListType = new TypeToken>>(){}.getType();
Result> userListResult = gson.fromJson(json,userType);
List users = userListResult.data;
4.使用GsonBuilder导出null值、格式化输出、日期时间
Gson gson = new GsonBuilder()
//序列化null
.serializeNulls()
// 设置日期时间格式,另有2个重载方法
// 在序列化和反序化时均生效
.setDateFormat("yyyy-MM-dd")
// 禁此序列化内部类
.disableInnerClassSerialization()
//生成不可执行的Json(多了 )]}' 这4个字符)
.generateNonExecutableJson()
//禁止转义html标签
.disableHtmlEscaping()
//格式化输出
.setPrettyPrinting()
.create();
4.排除无用的字段
方案1.使用transient关键字
方案2.使用Modifier为指定类型的字段(excludeFieldsWithModifiers(Modifier.PROTECTED))
方案3.使用@Expose,过滤无用(业务)字段
public class Category {
@Expose
public int id;
@Expose
public String name;
@Expose
public List children;
//不需要序列化,所以不加 @Expose 注解,
//等价于 @Expose(deserialize = false,serialize = false)
public Category parent;
}
Gson gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
gson.toJson(category);
方案4.基于策略(自定义规则),过滤无用(业务)字段
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
// 这里作判断,决定要不要排除该字段,return true为排除
if ("finalField".equals(f.getName())) return true;
//按字段名排除
Expose expose = f.getAnnotation(Expose.class);
if (expose != null && expose.deserialize() == false)
return true;
//按注解排除
return false;
}
@Override
public boolean shouldSkipClass(Class> clazz) {
// 直接排除某个类 ,return true为排除
return (clazz == int.class || clazz == Integer.class); }
})
.create();
5.处理混合类型的bean
//原json
{
"timestamp": 1449199363.89387,
"message": "Succeed",
"version": "1.0",
"results": [
{
"data": {
"recommended": 0,
"video_type": 2,
"vid": "23482078",
"title": "破风",
"movie_title": "破风",
"duration": "126",
"is_voted": 0,
"image": "http://i1.letvimg.com/lc02_isvrs/201509/11/16/21/a4bdc7ff-6d69-4875-bff8-dbe136a533ff/thumb/2_960_540.jpg",
"playcount": 3303475,
"share_link": "http://leying.duohappy.cn",
"desc": "无畏“破风手”传递正能量",
"code_rate": [
9,
13,
21,
22,
51
],
"is_downloadable": 0
},
"type": "video"
},
{
"data": {
"url": "http://www.baidu.com/",
"image": "http://i0.letvimg.com/lc02_isvrs/201506/11/16/26/dbbebacb-12f5-4356-a364-c9a888b884ba/thumb/2_1440_810.jpg",
"desc": "测试跳转描述",
"recommended": 1,
"title": "测试跳转"
},
"type": "link"
}
]
}
问题点是这个data数据,由于返回data数据,受到type的影响。无法固定List
public class VideoList {
public float timestamp;
public String message;
public String version;
public List
方案1.注册TypeAdapter
Gson gson = new GsonBuilder().registerTypeAdapter(VideoList.class, new VideoListJsonDeserializer()).create();
InputStream inputStream = getResources().openRawResource(R.raw.text);
VideoList videoList = gson.fromJson(new InputStreamReader(inputStream), VideoList.class);