Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的Java类库。 可以将一个 Json 字符转成一个 Java 对象,或者将一个 Java 对象转化为 Json 字符串。
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
<version>2.8.5version>
dependency>
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));
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));
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));
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));
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 是备选字段
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()
使用
序列化:将对象转化为json字符串。反序列化:将json字符串转化成对象
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) 使用
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();
GsonBuilder 提供了
setFieldNamingPolicy
和setFieldNamingStrategy
两个方法,用来设置字段序列和反序列时字段映射的规则
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"}
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();
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;
}
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)