使用Gson解析json成对象时默认的是将json里对应字段的值解析到java对象里对应字段的属性里面;但是开发中我们经常会遇到我们自己定义的java对象里的属性名跟json里的字段名是不一样的,这种情况怎么办呢,这时我们就可以使用@SerializedName注解来将对象里的属性跟json里字段对应值匹配起来。
比如:
返回的json格式如下:
{
"package": 0
}
我自己接受的类的属性定义如下:
public class User {
int id;
}
因为package和java的关键字冲突,java中无法定义package字段;
这个时候为了成功解析json,再User属性上加上 @SerializedName注解;
public class User {
@SerializedName("package")
int id;
}
加上@SerializedName(“package”) 之后,这个User类就可以成功接受上面的json了;
如果还有其他字段也想要User来接受怎么办?
{
"am": 0
}
或
{
"test": 0
}
这个时候还想使用User类接受的话使用alternate接受一个String数组
public class User {
@SerializedName(value = "package", alternate = {"am", "test"})
int id;
}
比如下面 private transient int value3 = 3;
BagOfPrimitives 类中的属性字段value3使用transient关键字就会避免被序列化,
这个类生成的对象中的values3字段不会被转到json里去;
public class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3; // 使用transient关键字会避免被序列化
}
// Gson解析
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
// ==> json is {"value1":1,"value2":"abc"}
{“value1”:1,“value2”:“abc”} 这串json中不会包含values字段
比如如下的json:
String json = “{“code”:1,“message”:“success”}”;
可以这样来解析
public class BaseModel {
public int code;
public String message;
}
Gson gson = new Gson();
BaseModel model= gson.fromJson(json,BaseModel.class);
使用上面的方法就可以解析了,但是实际开发中,我们不是这样的,我们需要泛型类定义,比如返回如下结构:
{
"code":200,
"message":"success",
"data":"{...}"
}
其中data对应的结构不定, 一种考虑是使用泛型:
定义如下:
public class BaseModel {
public int code;
public String message;
public T data;
}
T可以是任意的结构类型:
这个时候需要考虑这个泛型T,怎么去解析,gson中就要使用TypeToken来处理
public static BaseModel parse(String json, Class cls) {
Gson gson = new Gson();
BaseModel model = gson.fromJson(json, new TypeToken>() {
}.getType());
return model;
}
使用的User类
public class User {
public int age;
public String name;
}
使用的事例:
User user = new User("怪盗kidou", 24);
Gson gson = new GsonBuilder()
//为User注册TypeAdapter
.registerTypeAdapter(User.class, new UserTypeAdapter())
.create();
System.out.println(gson.toJson(user));
使用的UserTypeAdapter
public class UserTypeAdapter extends TypeAdapter {
//User对象转换成json
@Override
public void write(JsonWriter out, User user) throws IOException {
out.beginObject();
out.name("m").value(user.name);
out.name("a").value(user.age);
out.endObject();
//在这个方法里面,可以吧对象转换成任意的json字符串
}
//json转换成User对象
@Override
public User read(JsonReader in) throws IOException {
User user = new User();
in.beginObject();
while (in.hasNext()) {
switch (in.nextName()) {
case "m":
user.name = in.nextString();
break;
case "a":
user.age = in.nextInt();
break;
}
}
in.endObject();
return user;
}
//在这个方法里,可以吧json转换成对象
}
JsonSerializer 和JsonDeserializer 不用像TypeAdapter一样,必须要实现序列化和反序列化的过程,你可以据需要选择,如只接管序列化的过程就用 JsonSerializer ,只接管反序列化的过程就用 JsonDeserializer
反序列化
String json = "{\"age\":1,\"name\":\"success\"}";
Gson gson = new GsonBuilder()
//为User注册TypeAdapter
.registerTypeAdapter(User.class, new JsonDeserializer() {
@Override
public User deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
//这个方法把json序列化成User对象
Log.e("1234", "-----------: \n" + json.toString());
Log.e("1234", "-----------:\n" + json.isJsonObject());
JsonObject object = json.getAsJsonObject();
object.has("age");
Log.e("1234", "-----------age: " + (object.has("age")));
Log.e("1234", "-----------name: " + (object.has("name")));
Log.e("1234", "--------------:" + (object.size()));
object.keySet().iterator();
for (String str : object.keySet()) {
Log.e("1234", "--------------keySet: " + str);
}
for (Iterator> iterator = object.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry entry = iterator.next();
Log.e("1234", "---------------key: " + entry.getKey() + "------value: " + entry.getValue());
}
int age = object.getAsJsonPrimitive("age").getAsInt();
Log.e("1234", "----------------------age的值: " + age);
return new User(1, "11");
}
})
.create();
Log.e("1234", "--------------:\n " + gson.fromJson(json, User.class));
序列化
User u = new User(24, "火影忍者");
Gson gson = new GsonBuilder()
//为User注册TypeAdapter
.registerTypeAdapter(User.class, new JsonSerializer() {
@Override
public JsonElement serialize(User user, Type typeOfSrc, JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
jsonObject.add("age_age", new JsonPrimitive(user.age));
jsonObject.add("name_name", new JsonPrimitive(user.name));
return jsonObject;
}
})
.create();
Log.e("1234", "--------------:\n " + gson.toJson(u));