1.Android自带的Json类型:
1.1 基本类型
JsonElement是一个抽象类:
public abstract class JsonElement {}
JsonPrimitive比较最简单的JsonElement,用来将Objcet包装成一个JsonElement
public final class JsonPrimitive extends JsonElement {
private final Object value;
}
JsonObjec:
public final class JsonObject extends JsonElement {
//一个JsonObject可以被描述为一个map
private final LinkedTreeMap<String, JsonElement> members = new LinkedTreeMap<String, JsonElement>();
//可以看到String被包装成JsonElement存储在map中
public void addProperty(String property, String value) {
add(property, value == null ? JsonNull.INSTANCE : new JsonPrimitive(value));
}
}
JsonArray:
public final class JsonArray extends JsonElement implements Iterable<JsonElement> {
//JsonArray可以被描述为一个JsonElement组成的列表
private final List<JsonElement> elements;
//JsonArray不光可以存储JsonObject,还能以JsonPrimitive的形式存放数值,布尔值,字符等类型的数据
public void add(String string) {
elements.add(string == null ? JsonNull.INSTANCE : new JsonPrimitive(string));
}
}
1.2 Json的字符串形式:
JsonPrimitive:
JsonPrimitive primitive = new JsonPrimitive(9)
print(primitive.toString()); //输出:9
一个JsonObject用一个大括号限定范围:
JsonObject obj = new JsonObject();
obj.addProperty("name", "Tom");
obj.addProperty("age", 12);
print(obj.toString()); //输出:{"name":"Tom","age":12} 这里的12是不带引号的
一个JsonArray用一个中括号限定范围:
JsonArray array = new JsonArray();
JsonArray tempArray = new JsonArray();
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("name", "Tom");
jsonObject.addProperty("age", 12);
tempArray.add(jsonObject);
array.add(jsonObject);
array.add(tempArray);
array.add(6);
//这个JsonArray中包含了JsonObject,JsonArray,JsonPrimitive三种对象
//输出[{"name":"Tom","age":12},[{"name":"Tom","age":12}],6]
print(array.toString());
2.Gson使用
2.1 序列化和反序列化对象:
依赖:
implementation 'com.google.code.gson:gson:2.8.6'
创建Gson对象:
Gson gson = new Gson();
Gson gson1 = new GsonBuilder().create();
public class User {
private String name;
private int age;
1.字符串和单个对象互相转化:
void main(){
Gson gson = new Gson();
String userStr = "{\"age\":12,\"name\":\"Tom\"}";
User user = gson.fromJson(userStr,User.class) //字符串转换为对象
String userJsonStr = gson.toJson(user) //对象转换为字符串
}
2.字符串和对象数组或对象列表互相转化:
void main(){
Gson gson = new Gson();
String userStr = "[{\"age\":12,\"name\":\"Tom\"},{\"age\":13,\"name\":\"Sam\"}]";
//字符串转换为对象数组
User[] users = gson.fromJson(userStr, User[].class)
//试图把字符串转化为List<User>,实际上得到的是一个List<LinkedTreeMap>
ArrayList<User> list = gson.fromJson(userStr, new ArrayList<User>().getClass());
//User[]转换为字符串是可行的
gson.toJson(users);
//List<User>转化为字符串也是可行的
ArrayList list = new ArrayList();
list.add(new User("Tom", 12));
list.add(new User("Sam", 13));
gson.toJson(list);
}
3.成员变量有引用类型:
public class User {
private String name;
private int age;
private School school;
}
public class School {
private String name;
}
void main(){
String s = "{\"age\":12,\"name\":\"Tom\",\"school\":{\"name\":\"UESTC\"}}";
User user = gson.fromJson(s, User.class); //解析成功
gson.toJson(user); //{"age":12,"name":"Tom","school":{"name":"UESTC"}}
}
4.成员变量有对象数组或列表引用类型:
public class User {
private String name;
private int age;
private School[] school; //这里把School[]替换成ArrayList<School>依然可以解析成功
}
void main() {
String s = "{\"age\":12,\"name\":\"Tom\",\"school\":[{\"name\":\"UESTC\"},{\"name\":\"Tsinghua\"}]}";
User user = gson.fromJson(s, User.class) //解析成功
gson.toJson(user) //{"age":12,"name":"Tom","school":[{"name":"UESTC"},{"name":"Tsinghua"}]}
}
由于Gson可以方便地序列化和反序列化对象,所以可以用它来进行对象的深克隆
2.2 @SerializedName 注解
如果改动Json字符串,那么解析到User的name就为null:
String userStr = "{\"age\":12,\"username\":\"Tom\"}";
gson.fromJson(s, User.class) //user.name 为 null
@SerializedName 注解定义:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface SerializedName {
String value();
String[] alternate() default {};
}
为User的name加上SerializedName注解,这样就可以将其他一种或多种字符串映射为值相同的对象
public class User {
@SerializedName("userName")
private String name;
@SerializedName(value = "age", alternate = {"user_age", "Age"})
private int age;
2.3 @Expose 注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Expose {
boolean serialize() default true;
boolean deserialize() default true;
}
使用:
public class User {
//表示name字段可以被序列化,也可以被反序列化
@Expose(serialize = true, deserialize = true)
private String name;
另外Gson对象需要这样构建@Expose注解才会生效:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
基于修饰符决定是否需要序列化和反序列化
//这样创建Gson不会序列化和反序列化private和static修饰的成员变量
Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.PRIVATE, Modifier.STATIC).create();
基于某种策略决定是否需要序列化和反序列化
Gson gson = new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
//排除指定字段名
return fieldAttributes.getName().equals("intField");
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
//排除指定字段类型
return aClass.getName().equals(double.class.getName());
}
}).create();
TypeAdapter
public abstract class TypeAdapter<T> {
public abstract void write(JsonWriter var1, T var2) throws IOException;
public abstract T read(JsonReader var1) throws IOException;
}
自定义TypeAdapter:
public class UserTypeAdapter extends TypeAdapter<User> {
@Override
public void write(JsonWriter jsonWriter, User user) throws IOException {
//流式序列化成对象开始
jsonWriter.beginObject();
//将Json的Key值都指定为大写字母开头
jsonWriter.name("Name").value(user.getName());
jsonWriter.name("Age").value(user.getAge());
//流式序列化结束
jsonWriter.endObject();
}
@Override
public User read(JsonReader jsonReader) throws IOException {
User user = new User();
//流式反序列化开始
jsonReader.beginObject();
while (jsonReader.hasNext()) {
switch (jsonReader.nextName()) {
//首字母大小写均合法
case "name":
case "Name":
user.setName(jsonReader.nextString());
break;
case "age":
user.setAge(jsonReader.nextInt());
break;
}
}
//流式反序列化结束
jsonReader.endObject();
return user;
}
}
在Gson构造时注册TypeAdapter:
public static void main(String[] args) {
//注册TypeAdapter之后序列化和反序列化的过程都会受到UserTypeAdapter的影响
Gson gson = new GsonBuilder().registerTypeAdapter(User.class, new UserTypeAdapter()).create();
}
或者通过注解注册:
@JsonAdapter(UserTypeAdapter.class)
public class User {
private String name;
private int age;
}
GsonBuilder.registerTypeAdapter方法:
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|| typeAdapter instanceof JsonDeserializer<?>
|| typeAdapter instanceof InstanceCreator<?>
|| typeAdapter instanceof TypeAdapter<?>);
if (typeAdapter instanceof InstanceCreator<?>) {
instanceCreators.put(type, (InstanceCreator) typeAdapter);
}
if (typeAdapter instanceof JsonSerializer<?> || typeAdapter instanceof JsonDeserializer<?>) {
TypeToken<?> typeToken = TypeToken.get(type);
factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
}
if (typeAdapter instanceof TypeAdapter<?>) {
factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));
}
return this;
}
可以看到,除了TypeAdapter之外,这个方法还支持JsonSerializer 和 JsonDeserializer类型的参数
JsonSerializer 和 JsonDeserializer
JsonSerializer 和 JsonDeserializer是TypeAdapter拆分后得到的连个接口,作用与TypeAdapter相同,使用方法也和TypeAdapter完全相同,例如:
public class UserSerializer implements JsonSerializer<User> {
@Override
public JsonElement serialize(User src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("Name", user.getName());
jsonObject.addProperty("Age", user.getAge());
return jsonObject;
}
}
public class UserDeserializer implements JsonDeserializer<User> {
@Override
public User deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String name = jsonObject.get("name").getAsString();
int age = jsonObject.get("age").getAsInt();
return new User(name, age);
}
}
使用时可以在创建Gson对象时注册:
Gson gson = new GsonBuilder().registerTypeAdapter(User.class,new UserSerializer()).create();
或者像TypeAdapter一样通过注解:
@JsonAdapter(UserDeserializer.class)
public class User {
private String name;
private int age;
}
TypeAdapterFactory
TypeAdapterFactory提供了相对集中统一的方式去为某个特定的Model类型指定TypeAdapter:
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new TypeAdapterFactory() {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
//typeToken中可以获取到类的信息,对于某一特定的类返回特定的TypeAdapter
if (User.class.isAssignableFrom(typeToken.getRawType())) {
return (TypeAdapter<T>) new UserTypeAdapter();
}
//找不到则返回null,返回null就用默认的(反)序列化方法
return null;
}
}).create();