Google Gson 库使用总结

文章目录

      • jar 包依赖
      • map 和 json 字符串互转
      • json 数组字符串 转 数组或集合
      • json 字符串 和 JsonObject 互转
      • json字符串 和 对象 互转
      • @SerializedName 注解的使用
      • @Expose 注解的使用
      • @Since & @Until 注解的使用
      • 字段过滤-基于访问修饰符
      • 基于策略(自定义规则)
      • 自定义 对象 与 JSON 的字段映射规则
        • 基于 setFieldNamingPolicy 方式
        • 基于 setFieldNamingStrategy 方式
      • 手动实现反序列化
      • 自定义 gson
      • 使用 TypeAdapter 来序列化和反序列化

Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的Java类库。 可以将一个 Json 字符转成一个 Java 对象,或者将一个 Java 对象转化为 Json 字符串。

 

jar 包依赖

<dependency>
    <groupId>com.google.code.gsongroupId>
    <artifactId>gsonartifactId>
    <version>2.8.5version>
dependency>

map 和 json 字符串互转

Gson gson = new Gson();
String jsonStr = "{\"name\": \"answer\", \"value\": \"coder\"}";

// json字符串 转 map
HashMap map = gson.fromJson(jsonStr, HashMap.class);
System.out.println(map.get("name"));

// map 转 json字符串
System.out.println(gson.toJson(map));

 

json 数组字符串 转 数组或集合

Gson gson = new Gson();
String jsonArray = "[\"answer\", \"answerail\", \"ai\"]";
// json数组字符串 转 数组
String[] names = gson.fromJson(jsonArray, String[].class);
System.out.println(names[0]);
// 数组转 json数组字符串
System.out.println(gson.toJson(names));
System.out.println();

// json数组字符串 转 集合
List<String> nameList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());
System.out.println(nameList.get(0));
// 集合 转 json数组字符串
System.out.println(gson.toJson(nameList));

 

json 字符串 和 JsonObject 互转

String jsonStr = "{\"name\": \"answer\", \"value\": \"coder\"}";
Gson gson = new Gson();
// json 字符串 转 JsonObject
JsonObject jsonObject = gson.fromJson(jsonStr, JsonObject.class);
System.out.println(jsonObject.size() + "\t" + jsonObject.get("name"));
// JsonObject 转 json 字符串
System.out.println(gson.toJson(jsonObject));

 

json字符串 和 对象 互转

Gson gson = new Gson();
String jsonStr = "{\"id\": 1, \"name\": \"answer\", \"email\": \"[email protected]\", \"address\": \"pt\"}";

// json字符串 转 对象
User user = gson.fromJson(jsonStr, User.class);
System.out.println(user.getName());

// 对象 转 json字符串
System.out.println(gson.toJson(user));

 

@SerializedName 注解的使用

User user = User.builder().id(1L).name("answer").email("[email protected]").address("pt").build();
Gson gson = new Gson();
// 对象 转 json 字符串
String jsonStr = gson.toJson(user);
System.out.println(jsonStr);

// @SerializedName 中 value 或 alternate 的设置的属性值出现的任何一个都可被正确解析
// 如果把 userName 改为 name 即解析不了, 因为 name 不在 @SerializedName 设置的属性值中
jsonStr = "{\"id\":1,\"userName\":\"answer\",\"email\":\"[email protected]\",\"address\":\"pt\"}";
user = gson.fromJson(jsonStr, User.class);
System.out.println(user.getName());

// 如果出现多个属性值, 以最后一个出现的值为准, 如 login_Name 比 loginName 晚出现
jsonStr = "{\"id\":1,\"loginName\":\"answer\",\"email\":\"[email protected]\",\"address\":\"pt\", \"login_Name\": \"AnswerAIL\"}";
user = gson.fromJson(jsonStr, User.class);
System.out.println(user.getName());


@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long id;
    @SerializedName(value = "loginName", alternate = {"userName", "login_Name", "user_name"})
    private String name;
    private String email;
    private String address;
}

value 的值不能出现在 alternate 中,alternate 是备选字段

@Expose 注解的使用

User user = User.builder().id(1L).name("AnswerAIL").email("[email protected]").address("pt").build();
Gson gson = new Gson();
gson.toJson(user, System.out);
System.out.println();

// @Expose 注解必须配合 excludeFieldsWithoutExposeAnnotation 使用
gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
gson.toJson(user, System.out);
System.out.println();



@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Expose(serialize = true)
    private Long id;
    @SerializedName(value = "loginName", alternate = {"userName"})
    @Expose(serialize = true)
    private String name;
    @Expose(serialize = false)
    private String email;
    @Expose(serialize = true)
    private String address;
}

程序运行输出

{"id":1,"loginName":"AnswerAIL","email":"[email protected]","address":"pt"}
{"id":1,"loginName":"AnswerAIL","address":"pt"}
  • 默认是既可以序列化,也可以反序列化 Gson gson = new Gson();
  • 必须配合 excludeFieldWithoutExposeAnnotation() 使用
    • Gson gson = new GsonBuilder().excludeFieldWithoutExposeAnnotation().create();
  • 四种使用形式
    • @Expose(deserialize = false, serialize = false) 不做任何解析, 等同于不使用@Expose注解
    • @Expose(deserialize = true, serialize = false) 可以反序列化, 不可以序列化
    • @Expose(deserialize = false, serialize = true) 不可以反序列化, 可以序列化
    • @Expose(deserialize = true, serialize = true) 既可以反序列化, 也可以序列化

序列化:将对象转化为json字符串。反序列化:将json字符串转化成对象

 

@Since & @Until 注解的使用

User user = User.builder().id(1L).name("AnswerAIL").email("[email protected]").address("pt").build();
Gson gson = new GsonBuilder().setVersion(1.1).create();
System.out.printf("version 1.1\t");
gson.toJson(user, System.out);
System.out.println();

gson = new GsonBuilder().setVersion(1.2).create();
System.out.printf("version 1.2\t");
gson.toJson(user, System.out);
System.out.println();

gson = new GsonBuilder().setVersion(1.3).create();
System.out.printf("version 1.3\t");
gson.toJson(user, System.out);
System.out.println();

gson = new GsonBuilder().setVersion(1.4).create();
System.out.printf("version 1.4\t");
gson.toJson(user, System.out);
System.out.println();



@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Since(1.0)
    @Until(1.3)
    private Long id;
    @Since(1.2)
    private String name;
    @Until(1.3)
    private String email;
    private String address;
}

程序运行输出

version 1.1	{"id":1,"email":"[email protected]","address":"pt"}
version 1.2	{"id":1,"name":"AnswerAIL","email":"[email protected]","address":"pt"}
version 1.3	{"name":"AnswerAIL","address":"pt"}
version 1.4	{"name":"AnswerAIL","address":"pt"}

 

版本控制注解: @Since(double ver) & @Until(double ver) 需配合 setVersion(double n) 使用

  • @Since(double ver): 当 n >= ver 时,才会解析
  • @Until(double ver): 当 n < ver 时,才会解析

 

字段过滤-基于访问修饰符

UserInfo user = UserInfo.builder().id(1L).name("AnswerAIL").
    		email("[email protected]").address("pt").school("ptwz").build();
Gson gson = new GsonBuilder().
    // 排除了具有 private、static 修饰符的字段
    excludeFieldsWithModifiers(Modifier.PRIVATE, Modifier.STATIC).create();
gson.toJson(user, System.out);



@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {
    public final String SEPERATOR = "@";
    public static int count = 1;
    public String school;
    private Long id;
    private String name;
    private String email;
    private String address;
}

程序运行输出

{"SEPERATOR":"@","school":"ptwz"}

 

基于策略(自定义规则)

Gson gson = new GsonBuilder()
    // 序列化
    .addSerializationExclusionStrategy(new ExclusionStrategy() {
        // 返回值决定要不要排除该字段, return true为排除
        @Override
        public boolean shouldSkipField(FieldAttributes f) {
            // 根据字段名排除(过滤掉 email 字段)
            if ("email".equals(f.getName())) {
                return true;
            }
            // 获取 Expose 注解
            Expose expose = f.getAnnotation(Expose.class);
            // 根据 Expose 注解排除
            return expose != null && !expose.deserialize();
        }

        // 直接排除某个类, return true 为排除
        @Override
        public boolean shouldSkipClass(Class<?> clazz) {
            return (clazz == int.class || clazz == Integer.class);
        }
    }).create();



gson = new GsonBuilder()
    // 反序列化
    .addDeserializationExclusionStrategy(new ExclusionStrategy() {
        // 返回值决定要不要排除该字段, return true为排除
        @Override
        public boolean shouldSkipField(FieldAttributes f) {
            return false;
        }

        // 直接排除某个类, return true 为排除
        @Override
        public boolean shouldSkipClass(Class<?> clazz) {
            return false;
        }
    }).create();

 

自定义 对象 与 JSON 的字段映射规则

GsonBuilder 提供了 setFieldNamingPolicysetFieldNamingStrategy 两个方法,用来设置字段序列和反序列时字段映射的规则

基于 setFieldNamingPolicy 方式

UserInfo userInfo = UserInfo.builder().userName("AnswerAIL").build();
// 默认 EG: userName -> userName
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create();
gson.toJson(userInfo, System.out);
System.out.println();

// 小写 + '-' EG: userName -> user-name
gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES).create();
gson.toJson(userInfo, System.out);
System.out.println();

// 小写 + 下划线 EG: userName -> user_name
gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
gson.toJson(userInfo, System.out);
System.out.println();

// 驼峰式 + 首字母大写  EG: userName -> UserName
gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
gson.toJson(userInfo, System.out);
System.out.println();

// 驼峰式 + 空格 EG: userName -> User Name
gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES).create();
gson.toJson(userInfo, System.out);
System.out.println();



@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {
    private String userName;
}

程序运行输出

{"userName":"AnswerAIL"}
{"user-name":"AnswerAIL"}
{"user_name":"AnswerAIL"}
{"UserName":"AnswerAIL"}
{"User Name":"AnswerAIL"}

 

基于 setFieldNamingStrategy 方式

public enum MyFieldNamingPolicy implements FieldNamingStrategy {
    /** 字段增加前缀 */
    PREFIX_APPEND {
        @Override
        public String translateName(Field f) {
            // 实现自己的规则
            return "AI-" + f.getName();
        }
    }
}

// 测试用例代码
UserInfo userInfo = UserInfo.builder().id(1L).name("answer").build();
Gson gson = new GsonBuilder().setFieldNamingStrategy(MyFieldNamingPolicy.PREFIX_APPEND).create();
gson.toJson(userInfo, System.out);

程序运行输出

{"AI-SEPERATOR":"@","AI-id":1,"AI-name":"answer"}

setFieldNamingPolicy 方式本身也是基于 setFieldNamingStrategy, 因为 FieldNamingPolicy 也是实现了 FieldNamingStrategy 接口实现的

public enum FieldNamingPolicy implements FieldNamingStrategy {…}

注意: @SerializedName 注解拥有最高优先级,在加有 @SerializedName 注解的字段上 FieldNamingStrategy 不生效

 

手动实现反序列化

String jsonStr = "{\"name\": \"AnswerAIL\", \"email\": \"[email protected]\", \"age\": 20}";
JsonReader reader = new JsonReader(new StringReader(jsonStr));
reader.beginObject();
while (reader.hasNext()) {
    String key = reader.nextName();
    switch (key) {
        case "name":
            String name = reader.nextString();
            System.out.println(name);
            break;
        case "email":
            String email = reader.nextString();
            System.out.println(email);
            break;
        case "age":
            int age = reader.nextInt();
            System.out.println(age);
            break;
        default:
            System.out.println("error");
    }
}
reader.endObject();

 

自定义 gson

User user = User.builder().id(1L).name("AnswerAIL").email("[email protected]").birthDay(new Date()).build();
// 默认情况下, 如果字段值为 null 不进行序列化
Gson gson = new Gson();
gson.toJson(user, System.out);
System.out.println();

// 自定义 gson
gson = new GsonBuilder()
    // 序列化 值为 null 的字段
    .serializeNulls()
    // 设置日期时间格式
    .setDateFormat("yyyy-MM-dd")
    // 禁此序列化内部类
    .disableInnerClassSerialization()
    // 生成不可执行的Json(多了 )]}' 这4个字符)
    .generateNonExecutableJson()
    // 禁止转义html标签
    .disableHtmlEscaping()
    // 格式化输出
    .setPrettyPrinting()
    .create();
gson.toJson(user, System.out);
System.out.println();



@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long id;
    @SerializedName(value = "loginName", alternate = {"userName", "login_Name", "user_name"})
    private String name;
    private String email;
    private String address;
    private Date birthDay;
}

 

使用 TypeAdapter 来序列化和反序列化

User user = User.builder().id(1L).name("AnswerAIL").email("[email protected]").address("pt").build();
Gson gson = new GsonBuilder().create();
TypeAdapter<User> typeAdapter = gson.getAdapter(User.class);
// 使用 TypeAdapter 序列化
System.out.println(typeAdapter.toJson(user));

String jsonStr = "{\"id\":1,\"name\":\"AnswerAIL\",\"email\":\"[email protected]\",\"address\":\"pt\"}";
// 使用 TypeAdapter 反序列化
System.out.println(typeAdapter.fromJson(jsonStr));

程序运行输出

{"id":1,"name":"AnswerAIL","email":"[email protected]","address":"pt"}
User(id=1, name=AnswerAIL, email=answer_ljm@163.com, address=pt)

 

你可能感兴趣的:(Java类库)