Gson

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();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值