文章目录
- Gson基本操作
- Gson 概述与下载
- Gson (反)序列化 Java 对象
- JsonElement Json 元素
- JsonObject Json 对象
- JsonArray Json 数组
- JsonParser Json 解析
- GsonBuilder 构建 Gson
- JsonElement的简单说明
- JsonElement:
- JsonPrimitive:
- JsonNull:
- JsonArray:
- JsonObject:
Gson基本操作
String、JsonObject、JavaBean 互相转换
User user = new Gson().fromJson(jsonObject, User.class);User user = new Gson().fromJson(string, User.class);String string = new Gson().toJson(user);JsonObject jsonObject = new Gson().toJsonTree(user).getAsJsonObject();JsonObject jsonObject = new JsonParser().parse(string).getAsJsonObject();
String、JsonArray、List互相转换
List<User> userList = gson.fromJson(string, new TypeToken<List<User>>() {}.getType());List<User> userList = gson.fromJson(jsonArray, new TypeToken<List<User>>() {}.getType());String string = new Gson().toJson(userList);JsonArray jsonArray = new Gson().toJsonTree(userList, new TypeToken<List<User>>() {}.getType()).getAsJsonArray();JsonArray jsonArray = new JsonParser().parse(string).getAsJsonArray()
Gson 概述与下载
1、Java 解析 Json 最常用的类库有:google 的 Gson、阿里巴巴的 FastJson、以及 Jackson。这些都是非常优秀而且常用的库。
2、GSON 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库,可以快速的将一个 Json 字符转成一个 Java 对象,或者将一个 Java 对象转化为 Json 字符串。
3、gson 在 github 上开源地址:https://github.com/google/gson
Maven 依赖:gson 在 Maven 仓库地址:
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version>
</dependency>
Gson (反)序列化 Java 对象
1、com.google.gson.Gson 提供 toJson() 和 fromJson() 方法用于序列化与反序列化 Java 对象。
2、Gson 对象的 toJson 方法可以将 Java 基本数据类型、数组、以及 POJO 对象、List、Map 、JsonElement 等转为 json 格式的字符串,
3、Gson 对象的 fromJson 方法做与 toJson 相反的操作,将 json 格式的字符串转为基本数据类型、 POJO 对象、List、Map 、JsonElement 等
对象序列化 | |
---|---|
T fromJson(String json, Class classOfT) | 将指定的 Json 反序列化为指定类的对象,如果指定的类是泛型类型,则使用 fromJson(String, Type)方法。 |
T fromJson(String json, Type typeOfT) | 将指定的 Json 反序列化为指定类型的对象,如果指定的对象是泛型类型,则此方法很有用,对于非泛型对象,请改用 fromJson(String json, Class classOfT) |
T fromJson(JsonElement json, Class classOfT) | 将指定的 json 元素反序列化为指定类型的对象,如果指定的类是泛型类型,则使用 fromJson(JsonElement, Type) 方法。 |
T fromJson(JsonElement json, Type typeOfT) | |
T fromJson(Reader json, Class classOfT) T fromJson(Reader json, Type typeOfT) | 将从指定字符输入流读取的Json反序列化为指定类的对象,如果指定的类是泛型类型,则调用 {@link#fromJson(Reader,type)} |
序列化为对象 | |
String toJson(Object src) | 将指定的对象序列化为其等效的Json表示形式,当指定的对象不是泛型类型时,应使用此方法,如果对象是泛型类型,请改用 toJson(object,type). |
String toJson(Object src, Type typeOfSrc) | 将指定的对象(包括泛型类型的对象)序列化为其等效的Json表示形式,对于非泛型对象,请改用{@link#toJson(Object)} |
String toJson(JsonElement jsonElement) | 将 JsonElement 转换为其等效的JSON表示形式。 |
JsonElement toJsonTree(Object src) | 将指定的对象序列化为 JsonElement 的等效表示形式,当指定的对象不是泛型类型时,应使用此方法;如果对象是泛型类型,请改用{@link#toJsonTree(object,type)} |
JsonElement toJsonTree(Object src, Type typeOfSrc) |
JsonElement Json 元素
1、JsonObject、JsonArray、JsonPrimitive、JsonNull 都是 JsonElement 的子类,JsonElement 常用方法:
JsonElement deepCopy() | 返回此元素的深层副本,克隆。 |
---|---|
BigDecimal getAsBigDecimal() | 将此元素作为 BigDecimal 类型获取,如果元素不是 JsonPrimitive,则引发 ClassCastException, 如果元素不是有效的 BigDecimate,则 @throws NumberFormatException。 如果元素属于 JsonArray 类型,但包含多个元素,则引发 IllegalStateException。 |
BigInteger getAsBigInteger() | 将此元素作为 BigInteger 类型获取,如果元素不是 JsonPrimitive,则引发 ClassCastException, 如果元素不是有效的 BigInteger ,则 @throws NumberFormatException。 如果元素属于 JsonArray 类型,但包含多个元素,则引发 IllegalStateException。 |
boolean getAsBoolean() | 将此元素作为原始布尔值获取,如果元素不是 JsonPrimitive 并且不是有效的布尔值,则引发 ClassCastException, 如果元素属于 JsonArray 类型,但包含多个元素,则引发IllegalStateException |
byte getAsByte() | 将此元素作为原始 byte 值获取,如果元素不是 JsonPrimitive 并且不是有效的布尔值,则引发 ClassCastException, 如果元素属于 JsonArray 类型,但包含多个元素,则引发IllegalStateException |
其它 Java 基本数据类型也是同理:double getAsDouble()、char getAsCharacter()、float getAsFloat()、int getAsInt()、long getAsLong()、short getAsShort() | |
JsonArray getAsJsonArray() | 将此元素作为 JsonArray 获取,如果元素是其他类型的元素,则会生成 IlleglastateException 异常, 因此最好先调用 isJsonArray() 方法确保该元素是所需的类型,然后再使用此方法。 |
JsonObject getAsJsonObject() | 将此元素作为 JsonObject 获取,如果元素是其他类型的元素,则会引发 IlleglastateException 异常, 因此最好先通过调用 isJsonObject() 方法来确保该元素是所需类型之后使用此方法。 |
JsonPrimitive getAsJsonPrimitive() | 将此元素作为 JsonPrimitive 获取,如果元素是其他类型的元素,则会引发 IlleglastateException 异常, 因此最好先通过调用 isJsonPrimitive() 方法来确保该元素是所需的类型之后再使用此方法。JsonPrimitive 值可以是 Java 字符串、Java 基本数据类型及其包装器类型。 |
boolean isJsonArray() | 验证此元素是否为数组,如果此元素属于 JsonArray 类型,则返回 true,否则返回 false。 |
boolean isJsonNull() | 验证此元素是否表示 null 值,如果此元素的类型为 JsonNull,则返回 true,否则返回 false。 |
boolean isJsonObject() | 验证此元素是否为 JsonObject 对象。 |
boolean isJsonPrimitive() | 以验证此元素是否为 Java 数据类型。 |
/*** JsonPrimitive getAsJsonPrimitive():* 将此元素作为 JsonPrimitive 获取,如果元素是其他类型的元素,则会引发 IlleglastateException 异常,* 因此最好先通过调用 isJsonPrimitive() 方法来确保该元素是所需的类型之后再使用此方法。JsonPrimitive 值可以是 Java 字符串、Java 基本数据类型及其包装器类型。*/@Testpublic void test12() {String json = "[\"本级小计\",368.00,328.00,]";JsonElement sourceJsonElement = new JsonParser().parse(json);JsonArray jsonArray = sourceJsonElement.getAsJsonArray();for (int i = 0; i < jsonArray.size(); i++) {JsonElement jsonElement = jsonArray.get(i);if (jsonElement.isJsonPrimitive()) {JsonPrimitive jsonPrimitive = jsonElement.getAsJsonPrimitive();if (jsonPrimitive.isString()) {System.out.println(jsonPrimitive.getAsString());} else if (jsonPrimitive.isNumber()) {System.out.println(jsonPrimitive.getAsDouble());}}}}
JsonObject Json 对象
add(String property, JsonElement value) | 添加一个健-值对的成员,名称必须是字符串,但值可以是任意的 JsonElement 类型。 |
---|---|
addProperty(String property, Boolean value) | 添加布尔成员的便利方法,指定的值将转换为布尔值的 JsonPrimitive。 |
addProperty(String property, Character value) | 添加 char 成员的便利方法,指定的值将转换为字符的 JsonPrimitive。 |
addProperty(String property, Number value) | 添加 Number 成员的便利方法,指定的值将转换为数字的 JsonPrimitive。 |
addProperty(String property, String value) | 添加 String 成员的便利方法,指定的值将转换为数字的 JsonPrimitive。 |
Set<Map.Entry<String, JsonElement>> entrySet() | 返回此对象的所有成员,集合是有序的,与元素的添加顺序相同。 |
JsonElement get(String memberName) | 返回具有指定名称的成员。 |
JsonArray getAsJsonArray(String memberName) | 获取指定成员作为 JsonArray 的便利方法。 |
JsonObject getAsJsonObject(String memberName) | 获取指定成员作为 JsonObject 的便利方法。 |
JsonPrimitive getAsJsonPrimitive(String memberName) | 获取指定成员作为 JsonPrimitive 的便利方法。 |
boolean has(String memberName) | 检查此对象中是否存在具有指定名称的成员的便利方法。 |
Set keySet() | 返回所有成员的 key 值。 |
JsonElement remove(String property) | 从此 JsonObject 中删除指定的属性,返回被删除的属性。 |
int size() | 返回对象中键/值对的数目。 |
/*** int size():返回对象中键/值对的数目。* Set<String> keySet():返回所有成员的键值*/@Testpublic void jsonObject7() {String json = "{\"pId\":9527,\"pName\":\"华安\",\"isMarry\":true}";JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();System.out.println(jsonObject.size());Set<String> keySet = jsonObject.keySet();//3System.out.println(keySet);//[pId, pName, isMarry]}
JsonArray Json 数组
JsonArray()JsonArray(int capacity) | 两个构造器,一个是创建空的 Json 数组,一个是指定初始容量。 |
---|---|
add( Boolean value) | 将指定的布尔值添加到 json 数组,如 value 为 null,则添加 JsonNull。 |
add(Character value) | 将指定的 Character 值添加到 json 数组,如 value 为 null,则添加 JsonNull。 |
add(Number value) | 将指定的 Number 值添加到 json 数组,如 value 为 null,则添加 JsonNull。 |
add(String value) | 将指定的 String 值添加到 json 数组,如 value 为 null,则添加 JsonNull。 |
add(JsonElement value) | 将指定的 JsonElement 值添加到 json 数组,如 value 为 null,则添加 JsonNull。 |
addAll(JsonArray array) | 将指定数组中的所有元素添加到此 json 数组。 |
boolean contains(JsonElement element) | 如果此数组包含指定的元素,则返回true。 |
JsonElement get(int i) | 返回数组的第 i 个元素,如果下标越界,则抛异常 |
Iterator iterator() | 返回一个迭代器来导航数组的元,由于数组是一个有序列表,迭代器按照元素插入的顺序导航元素。 |
JsonElement remove(int index) | 删除此数组中指定位置的元素,向左移动任何后续元素(从其索引中减去一个),返回从数组中删除的元素。 |
boolean remove(JsonElement element) | 从该数组中删除第一个出现的指定元素(如果存在)。如果数组不包含元素,则它将保持不变。 |
JsonElement set(int index, JsonElement element) | 将此数组中指定位置的元素替换为指定元素,元素不能为null。 |
int size() | 返回数组的大小。 |
@Testpublic void test4() {JsonArray jsonArray = new JsonParser().parse("[{\"code\":200,\"msg\":\"成功\"}]").getAsJsonArray();JsonArray deepCopy = jsonArray.deepCopy();deepCopy.add("Yes");System.out.println(jsonArray);//[{"code":200,"msg":"成功"}]System.out.println(deepCopy);//[{"code":200,"msg":"成功"},"Yes"]}
JsonParser Json 解析
1、JsonParser 用于将 Json 字符内容解析为 json 元素 JsonElement。
JsonElement parse(Reader json) | 将指定的 JSON 字符串字符输入流解析为 Json 元素,如果指定的文本不是有效的 JSON 字符串,则抛出 JsonParseException 异常。 |
---|---|
JsonElement parse(String json) | 将指定的 JSON 字符串解析为 Json 元素,如果指定的文本不是有效的 JSON 字符串,则抛出 JsonParseException 异常。 |
@Testpublic void test1() {String json = "{\"id\":1000,\"name\":\"华安\",\"birthday\":\"Jul 13, 2020 8:46:42 PM\",\"marry\":true}";JsonParser jsonParser = new JsonParser();JsonElement jsonElement = jsonParser.parse(json);JsonObject jsonObject = jsonElement.getAsJsonObject();System.out.println(jsonObject);//{"id":1000,"name":"华安","birthday":"Jul 13, 2020 8:46:42 PM","marry":true}}
GsonBuilder 构建 Gson
1、对于默认配置的 Gson,直接使用 new Gson 更简单,当需要设置默认值以外的配置选项时,使用 GsonBuilder 构建器,调用它的各种配置方法,最后调用 create 方法创建 Gson 对象。
GsonBuilder serializeNulls() | 序列化空字段,默认情况下,Gson 序列化期间会忽略所有为 null 的字段 |
---|---|
GsonBuilder setDateFormat(String pattern) | 根据提供的模式序列化 Date 日期对象,可以多次调用,但只有最后一次调用将用于决定序列化格式。 |
GsonBuilder setFieldNamingPolicy(FieldNamingPolicy namingConvention)1、配置为在序列化和反序列化期间将特定命名策略应用于对象的字段。2、namingConvention:用于序列化和反序列化的 JSON 字段命名约定/策略,可选值如下:IDENTITY:使用对象默认的字段名称 UPPER_CAMEL_CASE:使用驼峰命名 UPPER_CAMEL_CASE_WITH_SPACES:将 Java 字段名的第一个’字母’在序列化为JSON格式时大写,单词之间用空格隔开 LOWER_CASE_WITH_UNDERSCORES:使用此命名策略将把 Java 字段名从大小写形式修改为全小写字段名,其中单词之间由下划线分隔 LOWER_CASE_WITH_DASHES:使用此命名策略将把 Java 字段名从大小写形式修改为全小写字段名,其中单词之间用破折号(-)分隔 LOWER_CASE_WITH_DOTS:使用此命名策略将 Java 字段名从大小写形式修改为全小写字段名,其中每个单词用点(.)分隔。 |
@Testpublic void test1() {Gson gson = new GsonBuilder().serializeNulls().setDateFormat("yyyy-MM-dd HH:mm:ss").setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create();Person person = new Person();person.setId(100);person.setBirthday(new Date());String toJson = gson.toJson(person);//{"id":100,"name":null,"birthday":"2020-07-19 11:37:35","marry":null}System.out.println(toJson);Person person1 = gson.fromJson(toJson, Person.class);//Person{id=100, name='null', birthday=Sun Jul 19 11:37:35 CST 2020, marry=null}System.out.println(person1);}
JsonElement的简单说明
JsonElement:
该类是一个抽象类,代表着json串的某一个元素。这个元素可以是一个Json(JsonObject)、可以是一个数组(JsonArray)、可以是一个Java的基本类型(JsonPrimitive)、当然也可以为null(JsonNull);JsonObject,JsonArray,JsonPrimitive,JsonNull都是JsonElement这个抽象类的子类。JsonElement提供了一系列的方法来判断当前的JsonElement
是否是上述子类的一种:比如isJsonObject()用来判断当前的json元素是否是一个Json对象,它的实现很简单且这里巧妙地应用了Java的多态机制:
public boolean isJsonObject() {return this instanceof JsonObject;}
同样的既然有isJsonObject()等这样的判断,该类也提供了把当前JsonElement作为上述子类的一种返回的方法:
public JsonObject getAsJsonObject() {if (isJsonObject()) {return (JsonObject) this;}throw new IllegalStateException("Not a JSON Object: " + this);}
各个JsonElement的关系可以用如下图表示:
JsonObject对象可以看成 name/values的集合,而这写values就是一个个JsonElement,他们的结构可以用如下图表示:
以上图片来源见文章底部的参考资料!
JsonPrimitive:
JsonElement的子类,该类对Java的基本类型及其对应的对象类进行了封装,并通过setValue方法为value赋值
private static final Class<?>[] PRIMITIVE_TYPES = { int.class, long.class, short.class,float.class, double.class, byte.class, boolean.class, char.class, Integer.class, Long.class,Short.class, Float.class, Double.class, Byte.class, Boolean.class, Character.class };private Object value;
需要注意的是对于Character类型的json元素需要特殊处理:
void setValue(Object primitive) {if (primitive instanceof Character) {// convert characters to strings since in JSON, characters are represented as a single// character stringchar c = ((Character) primitive).charValue();this.value = String.valueOf(c);} else {$Gson$Preconditions.checkArgument(primitive instanceof Number|| isPrimitiveOrString(primitive));this.value = primitive;}}
同时对于传入的其他json类型通过checkArgumeng进行过滤,如果不是是Number或者String和 PRIMITIVE_TYPES里的一种的话,就会抛出异常。
private static boolean isPrimitiveOrString(Object target) {if (target instanceof String) {return true;}//在这里是Java class的一个简单应用Class<?> classOfPrimitive = target.getClass();for (Class<?> standardPrimitive : PRIMITIVE_TYPES) {//isAssingableFrom方法的作用是判断classsOfPrimitive是否可以转换为standardPrimitive类型if (standardPrimitive.isAssignableFrom(classOfPrimitive)) {return true;}}return false;}
同样类似JsonElement,该类也提供了判断某一个json元素是否是某一类型的判断和把某一json元素作为某一类型返回的方法:
public boolean isNumber() {return value instanceof Number;}@Overridepublic Number getAsNumber() {return value instanceof String ? new LazilyParsedNumber((String) value) : (Number) value;}
对于Java几个基本类型用JsonPrimitive类进行了封装, 还遗漏了一个null的json元素,Gson也对它进行了单独的处理,就是JsonNull:
JsonNull:
该类没什么可说的,为不可变类。当然在json中所有的JsonNullObject 调用equals方法判断的话都是相等的。
JsonArray:
Json的数组包含的其实也是一个个Json串。所以不难猜出JsonArray中用一个集合类源码中用List来添加json数组中的每个元素。(详见源码,很简单)
JsonObject:
json对象类,包含了键值对,键是字符串类型,它的值是一个JsonElement。用 LinkedTreeMap<String, JsonElement> members来保存。