2016 June 22 —— JSON; framework

gson

JSON作为一种高效精简的数据传输格式,在互联网应用中随处可见,无论是前后端数据传输亦或是做其他处理,JSON对于应用是难以直接利用Java操作的,一般我们需要将JSON格式的数据转换为Java Entity进而利用操作对象的方式去操作转换后的数据,这一转换过程目前方式各异,当然也可以自己造轮子,有人利用反射形式构建Java Obj进行封装,无非是各种基本类型数据的构造,但是目前主流的并不需要这种比较笨拙的方式,开源的框架已经高效的解决了这些问题,如FastJson,gson,jackson等等,这里选取gson学习之;

gson的使用主要是Java对象与JSON对象的转换,其核心使用方式很简明:

  • toJson()

  • fromJSon()

优雅的控制 null 数据的包含与否:

gson默认不输出 Null,但是可以通过配置gson实例进行 null 输出:

Gson includeNullsGson = gsonBuilder.serializeNulls().create();

利用注解自定义输出名

有时候接口数据需要经常调整,代码又不想改来改去,可以利用这个方式去快速修改输出;

@SerializedName("custom_naming") private final String someField;

读写Stream流数据

toJson() 与 fromJson() 都有一个重载函数,利用流数据,前者可以简单的写入Json数据到流,后者可以读取流数据;

FileReader fileReader = new FileReader(“d:/output.json”); dev= gson.fromJson(fileReader, Developer.class);

gson的字段版本控制

GsonBuilder().setVersion(2.0)

class ExampleClass{
  String field=  "field";
  // this is in version 1.0
  @Since(1.0) String newField1 = "field 1";
  // following will be included in the version 1.1
  @Since(2.0) String newField2 = "field 2";
}

通过版本控制可以方便的在版本升级字段更改变更做出改变,很多时候结合字段自定义命名使用很强大;

html字符的转换问题

有时候我们会在输出中嵌入 特殊字符,如html字符,默认情况下,如 > < & 等字符将转义为对应unicode进行输出,而不会原字符输出,我们同样可以简单的通过 gsonbuilder配置让其原样输出:

new GsonBuilder().disableHtmlEscaping()

控制gson输出字段的几种方式

  • 序列化保留字段 transient,该修饰符修饰的字段不会被输出

  • 利用GsonBuilder配置 gson instance,控制输出 如 gsonBuilder.excludeFieldsWithModifiers(Modifier.PRIVATE);将不输出所有private字段

  • 利用expose注解控制输出,结合配置gson实例控制,属于比较常用的一种控制方式

class Developer {
  // this field will be included
  @Expose
  private String name;
  ……
}

Gson gson= GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()

以上的配置将输出所有配置expose属性的字段;

数组,集合与泛型序列化

数组:

int[] ints = {1, 2, 3, 4, 5};
String[] strings = {"abc", "def", "ghi"};
// Serialization
gson.toJson(ints);     // ==> [1,2,3,4,5]
// Deserialization
int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class);


集合:
Collection<Integer> ints = Lists.immutableList(1,2,3,4,5);
// Serialization
String json = gson.toJson(ints);  // ==> json is [1,2,3,4,5]
// Deserialization
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);

需要注意的是:在 JSON 转换为Java对象反序列过程中,针对集合类型,类型需要自行强制指定,而无法自动识别转换为哪一种集合数据;这一点应该比较好理解

泛型转换实例对比:

针对常规类型我们可以利用这样的形式做出gson使用:

gson.toJson(obj),我们默认使用了 gson.toJson(obj,obj.getClass())的形式;亦或者传递 MyClass.class类型信息,这些针对非泛型都是可以很好的适用;

而如果是泛型信息则无法正确传递:

class Foo<T> {
  T value;
}
Foo<Bar> foo = new Foo<Bar>();
gson.toJson(foo); // May not serialize foo.value correctly
gson.fromJson(json, foo.getClass()); // Fails to deserialize foo.value as Bar

//正确的方式如下
Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.toJson(foo, fooType);

这一点结合集合的转换是比较好理解的;

Gson的序列化与反序列化:

序列化: JavaBean to Json

反序列化: Json to JavaBean

  1. SerializedName 注解:
  • value字段 —— 序列化 或 反序列化均有效
  • alternate 字段—— 仅当反序列时有效

利用两个字段,可以灵活配置Model适用于多种Json情况,而省略一些Model类型;

  1. JsonSerializer 的自定义使用实现序列化 以及 JsonDeserializer 的反序列化得到JaveBean

  2. 高效的TypeAdapter的序列化与反序列化,TypeAdapter的使用正是去掉了JsonElement转换中间层,直接用流来解析数据,conger提高解析效率。

其他自定义高级属性

  • Custom Serialization and Deserialization

  • 使用 TypeAdapter 实现高效的解析 —— 避免(Serialization and Deserialization) 在转换时产生的中间临时对象


Quote:

Gson User Guide

Java Google Json (Gson) Introduction

完全理解Gson系列

Getting Started with Google GSON

GSON - Gson

GSON DESERIALISER EXAMPLE

GSON TYPEADAPTER EXAMPLE – 更加高效的序列化方式

Gson全解析(上)-Gson基础

GSON TYPEADAPTER EXAMPLE – 更高效的自定义解析方式

上一篇
下一篇
Loading Disqus comments...
Table of Contents