您的位置:首页 > 其它

【Gson】简介 文档 基本使用 示例

2017-09-12 14:36 513 查看

简介

GitHub:https://github.com/google/gsongson-2.8.1.jar API user guide
compile 'com.google.code.gson:gson:2.8.1'
A Java serialization/deserialization library to convert Java Objects into JSON and back
将Java对象转换为JSON以及反过来的Java序列化/反序列化库
Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。而JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成,广泛应用于各种数据的交互中,尤其是服务器与客户端的交互。

使用时需要注意的一些细节

使用Gson反序列化时,只有当JSON串中的 key 和JavaBean中的 field 完全一致时才能成功解析此field
class Person {
public String name;
}
System.out.println(gson.fromJson("{'name':'包青天'}", Person.class).name);//包青天。引号既可以是单引号也可以是双引号
System.out.println(gson.fromJson("{\"name\":10086}", Person.class).name);//10086。任何类型的value都可以不带引号(包括String)
System.out.println(gson.fromJson("{'NAME':'包青天'}", Person.class).name);//null。严格区分大小写
使用Gson反序列化时,JSON串中的 key 对应的类型一定要和JavaBean中的 field 定义的类型相匹配,否则解析时会报错

class Person {
public int age;
}
System.out.println(gson.fromJson("{'age':0xff}", Person.class).age);//NumberFormatException。只能解析十进制数
System.out.println(gson.fromJson("{'age':true}", Person.class).age);//Expected an int but was BOOLEAN
System.out.println(gson.fromJson("{'age':1.23}", Person.class).age);//Expected an int but was 1.23
使用Gson反序列化时,对JavaBean中的 field 的访问限制符是public还是private没任何要求,对构造方法也没任何要求

使用Gson反序列化时,在解析JSON数据前需要自己确定待解析的是JSON Object还是JSON array

JSON串中的false、true和JavaBean中的整型0、1之间不能相互转换

JSON串中用不着的字段可以不在JavaBean中声明
JSON串中的引号既可以是单引号也可以是双引号,且任何类型的value都可以不带引号(包括String)

JSON串中的key只能是string类型的,而value可以是string、number、false/true、null、Object对象或者array数组

google-gson 文档









Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.

Gson是一个可用于将Java对象转换为JSON表示形式的Java库。它也可以用于将JSON字符串转换为等效的Java对象。 Gson可以和任意Java对象一起使用,包括您没有源代码的预先存在的对象。

There are a few open-source projects that can convert Java objects to JSON. However, most of them require that you place Java annotations in your classes; something that you can not do if you do not have access to the source-code. Most also do not fully support the use of Java Generics. Gson considers both of these as very important design goals.有几个开源项目可以将Java对象转换为JSON。但是,他们大多数都要求您将Java注解放在类中;如果您无法访问源代码,则无法执行此操作。大多数也不完全支持使用Java泛型。 Gson认为这两个都是非常重要的设计目标。

Gson Goals目标Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice-versa 提供简单的toJson()和fromJson()方法将Java对象转换为JSON,反之亦然
Allow pre-existing unmodifiable objects to be converted to and from JSON 允许将先前存在的不可修改对象转换为JSON或从JSON转换
Extensive support of Java Generics 广泛的支持Java泛型
Allow custom representations for objects 允许对象的自定义表示

Gson Download and MavenGson Download downloads at Maven Central
For Maven check "Dependency Information" tab, on the left side.

Gson Documentation文档Gson API: Javadocs for the current Gson release 当前Gson版本的Javadoc
Gson user guide: This guide contains examples on how to use Gson in your code. 本指南包含有关如何在代码中使用Gson的示例。
Gson Roadmap: Details of changes in the recent versions 最近版本更改的详细信息
Gson design document: This document discusses issues we faced while designing Gson. It also include a comparison of Gson with other Java libraries that can be used for Json conversion 本文档讨论了我们在设计Gson时遇到的问题。它还包括将Gson与可用于Json转换的其他Java库进行比较
Please use the google-gson Google group to discuss Gson, or to post questions.
Gson-related Content Created by Third Parties 由第三方创建的Gson相关内容Gson Tutorial by StudyTrails Gson教程
Gson Tutorial Series by Future Studio Gson系列教程

Gson使用时的混淆问题

遇到的问题:在不使用混淆工具进行apk打包时,一切正常;在使用混淆编译的方式进行apk打包后,就不能获取到JavaBean中的值了!

可能的原因:使用Gson的fromJson方法反序列化时,要求 JavaBean 中的字段名必须与 json 串中的 key 完全一致,否则解析失败。而混淆后, JavaBean 的类名及其字段名称全部变成了A、B、C或a、b、c等简称了,这与 json 串中的 key 不一致,进而导致解析失败。

解决办法:在使用混淆编译方式进行apk打包的时候,需要过滤掉所有相关的 JavaBean 。

在proguard.cfg文件中添加下面的代码:
#滤掉某个Java Bean 文件不进行混淆编译
-keep class com.lokinfo.m95xiu.bean.FamilyAssBean {*;}
#滤掉某个包下的所有.class文件不进行混淆编译
-keep class com.lokinfo.m95xiu.bean.** {*;}

GsonBuilder API

Gson create() Creates a Gson instance based on the current configuration. 根据当前配置创建一个Gson实例。

addDeserializationExclusionStrategy(ExclusionStrategy strategy) Configures Gson to apply the passed in exclusion strategy during deserialization. 配置Gson在反序列化期间应用传递的排除策略。设置反序列化时字段采用策略ExclusionStrategy,如反序列化时不要某字段,当然可以采用@Expore代替。

addSerializationExclusionStrategy(ExclusionStrategy strategy) Configures Gson to apply the passed in exclusion strategy during serialization. 同上
disableHtmlEscaping() By default, Gson escapes HTML characters such as < > etc. 默认情况下,Gson转义HTML字符,如<>等。禁止转义html标签

disableInnerClassSerialization() Configures Gson to exclude inner classes during serialization. 配置Gson在序列化期间排除内部类。

enableComplexMapKeySerialization() Enabling this feature will only change the serialized form if the map key is a complex type (i.e. 启用此功能将仅在映射密钥为复杂类型时更改序列化形式。

excludeFieldsWithModifiers(int... modifiers) Configures Gson to excludes all class fields that have the specified modifiers. 将Gson配置为排除具有指定修饰符的所有类字段。参数值由java.lang.reflect.Modifier提供。

excludeFieldsWithoutExposeAnnotation() Configures Gson to exclude all fields from consideration for serialization or deserialization that do not have the Expose annotation. 将Gson配置为将所有字段排除在不具有“公开”注释的序列化或反序列化中。设置没有@Expore则不序列化和反序列化。

generateNonExecutableJson() Makes the output JSON non-executable in Javascript by prefixing the generated JSON with some special text. 通过使用一些特殊文本将生成的JSON前缀,使JSON中的输出JSON不可执行。在生成的Json串前多了【)]}'】这4个字符,且之后有一个换行

registerTypeAdapter(Type type, Object typeAdapter) Configures Gson for custom serialization or deserialization. 配置Gson以进行自定义序列化或反序列化。为某特定对象设置固定的序列和反序列方式,实现JsonSerializer和JsonDeserializer接口

registerTypeAdapterFactory(TypeAdapterFactory factory) Register a factory for type adapters. 为工厂注册类型适配器。

registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) Configures Gson for custom serialization or deserialization for an inheritance type hierarchy. 为继承类型层次结构的自定义序列化或反序列化配置Gson。

serializeNulls() Configure Gson to serialize null fields. 配置Gson序列化空字段。

serializeSpecialFloatingPointValues() Section 2.4 of JSON specification disallows special double values (NaN, Infinity, -Infinity). JSON规范的第2.4节不允许特殊的双重值(NaN,Infinity,-Infinity)。
setDateFormat(String pattern) Configures Gson to serialize Date objects according to the pattern provided. 根据提供的样式,将Gson配置为序列化Date对象。设置日期时间格式,在序列化和反序化时均生效

setDateFormat(int style) Configures Gson to to serialize Date objects according to the style value provided. 同上
setDateFormat(int dateStyle, int timeStyle) Configures Gson to to serialize Date objects according to the style value provided. 同上
setExclusionStrategies(ExclusionStrategy... strategies) Configures Gson to apply a set of exclusion strategies during both serialization and deserialization. 配置Gson在序列化和反序列化期间应用一组排除策略。

setFieldNamingPolicy(FieldNamingPolicy namingConvention) Configures Gson to apply a specific naming policy to an object's field during serialization and deserialization. 配置Gson在序列化和反序列化期间,将特定的命名策略应用于对象的字段。值从枚举FieldNamingPolicy 中获取。

setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) Configures Gson to apply a specific naming policy strategy to an object's field during serialization and deserialization. 即:设置字段序列和反序列时名称显示,和@Serializer的作用一致。

setLenient() By default, Gson is strict and only accepts JSON as specified by RFC 4627. 默认情况下,Gson是严格的,只接受RFC 4627规定的JSON。

setLongSerializationPolicy(LongSerializationPolicy serializationPolicy) Configures Gson to apply a specific serialization policy for Long and long objects. 配置Gson为长对象应用特定的序列化策略。

setPrettyPrinting() Configures Gson to output Json that fits in a page for pretty printing. 配置Gson来输出适合漂亮打印的页面的Json。

setVersion(double ignoreVersionsAfter) Configures Gson to enable versioning support. 配置Gson以启用版本控制支持。是和@Since 和 @Until 一起使用的。

Gson、FastJson、Jackson性能对比

参考 参考2 【JSON序列化 Object => JSON】
类库样本数量执行次数最长时间(毫秒)最短时间(毫秒)平均时间(毫秒)
FastJson
100000102291.221416.701454.93
Jackson100000101980.92841.91880.82
Gson100000102383.021469.081520.38
【JSON反序列化 JSON => Object】

类库样本数量执行次数最长时间(毫秒)最短时间(毫秒)平均时间(毫秒)
FastJson
100000107942.316340.556526.41
Jackson100000107957.226623.856815.41
Gson100000108235.157006.067364.75
【总结】

把Java对象JSON序列化,Jackson速度最快,在测试中比Gson快接近50%,FastJson和Gson速度接近。
把JSON反序列化成Java对象,FastJson、Jackson速度接近,Gson速度稍慢,不过差距很小。

示例代码1_对象、数组、集合序列化

public class Test {
public static Gson gson = new GsonBuilder().create();

public static void main(String[] args) {
objToJson();//普通对象
arrayToJson();//数组
listToJson();//集合
}

/**普通对象*/
public static void objToJson() {
String jsonString = gson.toJson(new Person("包青天", "广州"));
System.out.println("【JSON序列化  Object => JSON】" + jsonString);
Person person = gson.fromJson(jsonString, Person.class);//也可以用【new TypeToken<Person>() {}.getType()】
System.out.println("【JSON反序列化 JSON => Object】" + person);
}

/**数组*/
public static void arrayToJson() {
String jsonString = gson.toJson(new String[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" });
System.out.println("\n【JSON序列化  Array => JSON】" + jsonString);
String[] array = gson.fromJson(jsonString, String[].class);//也可以用【new TypeToken<String[]>() {}.getType()】
System.out.println("【JSON反序列化 JSON => Array】" + Arrays.toString(array));
//二维数组
String jsonString2 = gson.toJson(new int[][] { { 1, 2, 3 }, { 3, 4, 5 }, { 4, 5, 6 } });
System.out.println("\n【JSON序列化  Array => JSON】" + jsonString2);
int[][] array2 = gson.fromJson(jsonString2, int[][].class);
System.out.println("【JSON反序列化 JSON => Array】" + Arrays.toString(array2));
}

/**集合*/
public static void listToJson() {
//List
List<Person> persons = new ArrayList<Person>();
persons.add(new Person("包青天", "北京"));
persons.add(new Person("白乾涛", "上海"));
persons.add(new Person("bqt", "广州"));

String jsonString = gson.toJson(persons);
System.out.println("\n【JSON序列化  List => JSON】" + jsonString);
List<Person> persons2 = gson.fromJson(jsonString, new TypeToken<List<Person>>() {
}.getType());//支持带泛型
System.out.println("【JSON反序列化 JSON => List】" + persons2.toString());

//Map
Map<String, Integer> names = new HashMap<String, Integer>();
names.put("包青天", 1);
names.put("白乾涛", 2);
names.put("bqt", 3);

String jsonString2 = gson.toJson(names);
System.out.println("\n【JSON序列化  Map => JSON】" + jsonString2);
Map<String, Integer> names2 = gson.fromJson(jsonString2, new TypeToken<Map<String, Integer>>() {
}.getType());
System.out.println("【JSON反序列化 JSON => Map】" + names2.toString());
}
}
Bean

class Person {
public String name;//对字段的访问限制符public还是private没任何限制,但字段名必须和Json串中的完全一致
public String address;

public Person(String name, String address) {//对构造方法也没任何限制
this.name = name;
this.address = address;
}

@Override
public String toString() {
return "name=" + name + " & " + "address=" + address;
}
}


示例代码2_解析Json串

/**解析Json串*/
public static void parserJson() {
String json = "{'flag':true,'data':{'name':'张三','age':18,'address':'广州'}}";
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(json);// 获得根节点元素
JsonObject root = element.getAsJsonObject();//必须事先知道根节点是 JsonObject还是JsonArray ,框架本身没法帮你决定
JsonPrimitive flagJson = root.getAsJsonPrimitive("flag");//取得根节点下的某个节点的值
boolean flag = flagJson.getAsBoolean();
System.out.println("\n【解析Json串】" + flag);

JsonObject dataJson = root.getAsJsonObject("data");//逐层向内解析
Person person = gson.fromJson(dataJson, Person.class);
System.out.println("【JSON反序列化】" + person);
}


示例代码3_内部类

String jsonString = "{'name':'包青天','age':28,'innerClass':{'flag':true}}";
Person person = gson.fromJson(jsonString, Person.class);
System.out.println(person);//[name=包青天, age=28, innerClass=[flag=true]]
System.out.println(gson.toJson(person));//{"name":"包青天","age":28,"innerClass":{"flag":true}}
class Person {
private String name;//可以定义为私有的
public int age;
InnerClass innerClass;

@Override
public String toString() {
return "[name=" + name + ", age=" + age + ", innerClass=" + innerClass + "]";
}

private static class InnerClass {//可以定义为私有的
boolean flag;

@Override
public String toString() {
return "[flag=" + flag + "]";
}
}
}
2017-9-12
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: