Google -gson 最全的文档

Gson User Guide

Authors: Inderjeet Singh, Joel Leitch, Jesse Wilson

Overview

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 is an open-source project hosted at http://code.google.com/p/google-gson.Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.

Goals for Gson

  • Provide easy to use mechanisms like toString() and constructor (factory method) to convert Java to JSON and vice-versa
  • Allow pre-existing unmodifiable objects to be converted to and from JSON
  • Allow custom representations for objects
  • Support arbitrarily complex object
  • Generate compact and readability JSON output

Gson Users

Gson was originally created for use inside Google where it is currently used in a number of projects. It is now used by a number of public projects and companies. See details here.

Using Gson

The primary class to use is Gson which you can just create by calling new Gson(). There is also a class GsonBuilder available that can be used to create a Gson instance with various settings like version control and so on.

The Gson instance does not maintain any state while invoking Json operations. So, you are free to reuse the same object for multiple Json serialization and deserialization operations.

Primitives Examples

(Serialization)
Gson gson = new Gson();
gson.toJson(1);            ==> prints 1
gson.toJson("abcd");       ==> prints "abcd"
gson.toJson(new Long(10)); ==> prints 10
int[] values = { 1 };
gson.toJson(values);       ==> prints [1]

(Deserialization)
int one = gson.fromJson("1", int.class);
Integer one = gson.fromJson("1", Integer.class);
Long one = gson.fromJson("1", Long.class);
Boolean false = gson.fromJson("false", Boolean.class);
String str = gson.fromJson("\"abc\"", String.class);
String anotherStr = gson.fromJson("[\"abc\"]", String.class);

Object Examples

class BagOfPrimitives {
  private int value1 = 1;
  private String value2 = "abc";
  private transient int value3 = 3;
  BagOfPrimitives() {
    // no-args constructor
  }
}

(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
==> json is {"value1":1,"value2":"abc"}

Note that you can not serialize objects with circular references since that will result in infinite recursion.

(Deserialization)
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
==> obj2 is just like obj

Array Examples

son gson = new Gson();
int[] ints = {1, 2, 3, 4, 5};
String[] strings = {"abc", "def", "ghi"};

(Serialization)
gson.toJson(ints);     ==> prints [1,2,3,4,5]
gson.toJson(strings);  ==> prints ["abc", "def", "ghi"]

(Deserialization)
int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class);
==> ints2 will be same as ints

We also support multi-dimensional arrays, with arbitrarily complex element types

Collections Examples

Gson gson = new Gson();
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);
ints2 is same as ints

Serializing and Deserializing Generic Types

When you call toJson(obj), Gson calls obj.getClass()to get information on the fields to serialize. Similarly, you can typically pass MyClass.classobject in the fromJson(json, MyClass.class) method. This works fine if the object is a non-generic type. However, if the object is of a generic type, then the Generic type information is lost because of Java Type Erasure. Here is an example illustrating the point:

class Foo<T> {
  T value;
}
Gson gson = new Gson();
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

The above code fails to interpret value as type Bar because Gson invokes list.getClass() to get its class information, but this method returns a raw class, Foo.class. This means that Gson has no way of knowing that this is an object of type Foo, and not just plain Foo.

You can solve this problem by specifying the correct parameterized type for your generic type. You can do this by using the TypeToken class.

Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.toJson(foo, fooType);

gson.fromJson(json, fooType);

The idiom used to get fooTypeactually defines an anonymous local inner class containing a method getType()that returns the fully parameterized type.

Serializing and Deserializing Collection with Objects of Arbitrary Types

Sometimes you are dealing with JSON array that contains mixed types. For example:

[‘hello‘,5,{name:‘GREETINGS‘,source:‘guest‘}]

The equivalent Collection containing this is:

Collection collection = new ArrayList();
collection.add("hello");
collection.add(5);
collection.add(new Event("GREETINGS", "guest"));

Where the Event class is defined as:

class Event {
  private String name;
  private String source;
  private Event(String name, String source) {
    this.name = name;
    this.source = source;
  }
}

You can serialize the collection with Gson without doing anything specific: toJson(collection)would write out the desired output.

However, deserialization with fromJson(json, Collection.class) will not work since Gson has no way of knowing how to map the input to the types. Gson requires that you provide a genericised version of collection type in fromJson. So, you have three options:

Custom Serialization and Deserialization

Sometimes default representation is not what you want. This is often the case when dealing with library classes (DateTime, etc).

  • Gson allows you to register your own custom serializers and deserializers. This is done by defining two parts:

    Json Serialiers: Need to define custom serialization for an object

  • Json Deserializers: Needed to define custom deserialization for a type
  • Instance Creators: Not needed if no-args constructor is available or a deserializer is registered
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(MyType2.class, new MyTypeAdapter());
gson.registerTypeAdapter(MyType.class, new MySerializer());
gson.registerTypeAdapter(MyType.class, new MyDeserializer());
gson.registerTypeAdapter(MyType.class, new MyInstanceCreator());

registerTypeAdapter call checks if the type adapter implements more than one of these interfaces and register it for all of them.

Writing a Serializer

Here is an example of how to write a custom serializer for JodaTime DateTime class.

private class DateTimeSerializer implements JsonSerializer<DateTime> {
  public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) {
    return new JsonPrimitive(src.toString());
  }
}

Gson calls toJson() when it runs into a DateTime object during serialization.

Writing a Deserializer

Here is an example of how to write a custom deserializer for JodaTime DateTime class.

private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
  public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    return new DateTime(json.getAsJsonPrimitive().getAsString());
  }
}

Finer points with Serializers and Deserializers

Often you want to register a single handler for all generic types corresponding to a raw type

For example, suppose you have an “Id” class for Id representation/translation (i.e. an internal vs. external representation).

Id type that has same serialization for all generic types

Essentially write out the id value

Deserialization is very similar but not exactly the same

Need to call “new Id(Class, String)” which returns an instance of Id

Gson supports registering a single handler for this. You can also register a specific handler for a specific generic type (say Id needed special handling).

The Type parameter for the toJson and fromJson contains the generic type information to help you write a single handler for all generic types corresponding to the same raw type

Writing an Instance Creator

While deserializing an Object, Gson needs to create a default instance of the class

Well-behaved classes that are meant for serialization and deserialization should have a no-argument constructor

Doesn’t matter whether public or private

Typically, Instance Creators are needed when you are dealing with a library class that does NOT define a no-argument constructor

Instance Creator Example

private class MoneyInstanceCreator implements InstanceCreator<Money> {
  public Money createInstance(Type type) {
    return new Money("1000000", CurrencyCode.USD);
  }
}

Type could be of a corresponding generic type

Very useful to invoke constructors which need specific generic type information

For example, if the Id class stores the class for which the Id is being created

InstanceCreator for a Parameterized Type

Sometimes that the type that you are trying to instantiate is a parameterized type. Generally, this is not a problem since the actual instance is of raw type. Here is an example:

class MyList<T> extends ArrayList<T> {
}

class MyListInstanceCreator implements InstanceCreator<MyList<?>> {
    @SuppressWarnings("unchecked")
  public MyList<?> createInstance(Type type) {
    // No need to use a parameterized list since the actual instance will have the raw type anyway.
    return new MyList();
  }
}

However, sometimes you do need to create instance based on the actual parameterized type. In this case, you can use the type parameter being passed to the createInstance method. Here is an example: 

public class Id<T> {
  private final Class<T> classOfId;
  private final long value;
  public Id(Class<T> classOfId, long value) {
    this.classOfId = classOfId;
    this.value = value;
  }
}

class IdInstanceCreator implements InstanceCreator<Id<?>> {
  public Id<?> createInstance(Type type) {
    Type[] typeParameters = ((ParameterizedType)type).getActualTypeArguments();
    Type idType = typeParameters[0]; // Id has only one parameterized type T
    return Id.get((Class)idType, 0L);
  }
}

In the above example, an instance of the Id class can not be created without actually passing in the actual type for the parameterized type. We solve this problem by using the passed method parameter, type. The type object in this case is the Java parameterized type representation of Id where the actual instance should be bound to Id. Since Id class has just one parameterized type parameter, T, we use the zeroth element of the type array returned by getActualTypeArgument() which will hold Foo.class in this case.

Compact Vs. Pretty Printing for JSON Output Format

The default JSON output that is provide by Gson is a compact JSON format. This means that there will not be any whitespace in the output JSON structure. Therefore, there will be no whitespace between field names and its value, object fields, and objects within arrays in the JSON output. As well, “null” fields will be ignored in the output (NOTE: null values will still be included in collections/arrays of objects). See the Null Object Support section for information on configure Gson to output all null values.

If you like to use the Pretty Print feature, you must configure your Gson instance using the GsonBuilder. The JsonFormatter is not exposed through our public API, so the client is unable to configure the default print settings/margins for the JSON output. For now, we only provide a default JsonPrintFormatter that has default line length of 80 character, 2 character indentation, and 4 character right margin.

The following is an example shows how to configure a Gson instance to use the default JsonPrintFormatter instead of the JsonCompactFormatter:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);

Null Object Support

The default behaviour that is implemented in Gson is that null object fields are ignored. This allows for a more compact output format; however, the client must define a default value for these fields as the JSON format is converted back into its Java.

Here’s how you would configure a Gson instance to output null:

Gson gson = new GsonBuilder().serializeNulls().create();

NOTE: when serializing nulls with Gson, it will add a JsonNull element to the JsonElement structure. Therefore, this object can be used in custom serialization/deserialization.

Here’s an example:

public class Foo {
  private final String s;
  private final int i;

  public Foo() {
    this(null, 5);
  }

  public Foo(String s, int i) {
    this.s = s;
    this.i = i;
  }
}

Gson gson = new GsonBuilder().serializeNulls().create();
Foo foo = new Foo();
String json = gson.toJson(foo);
System.out.println(json);

json = gson.toJson(null);
System.out.println(json);

======== OUTPUT ========
{"s":null,"i":5}
null

Versioning Support

Multiple versions of the same object can be maintained by using @Since annotation. This annotation can be used on Classes, Fields and, in a future release, Methods. In order to leverage this feature, you must configure your Gson instance to ignore any field/object that is greater than some version number. If no version is set on the Gson instance then it will serialize and deserialize all fields and classes regardless of the version.

public class VersionedClass {
  @Since(1.1) private final String newerField;
  @Since(1.0) private final String newField;
  private final String field;

  public VersionedClass() {
    this.newerField = "newer";
    this.newField = "new";
    this.field = "old";
  }
}

VersionedClass versionedObject = new VersionedClass();
Gson gson = new GsonBuilder().setVersion(1.0).create();
String jsonOutput = gson.toJson(someObject);
System.out.println(jsonOutput);
System.out.println();

gson = new Gson();
jsonOutput = gson.toJson(someObject);
System.out.println(jsonOutput);

======== OUTPUT ========
{"newField":"new","field":"old"}

{"newerField":"newer","newField":"new","field":"old"}

Excluding Fields From Serialization and Deserialization

Gson supports numerous mechanisms for excluding top-level classes, fields and field types. Below are pluggable mechanism that allow field and class exclusion. If none of the below mechanism satisfy your needs then you can always use custom serializers and deserializers.

Java Modifier Exclusion

By default, if you mark a field as transient, it will be excluded. As well, if a field is marked as “static” then by default it will be excluded. If you want to include some transient fields then you can do the following:

import java.lang.reflect.Modifier;

Gson gson = new GsonBuilder()
    .excludeFieldsWithModifiers(Modifier.STATIC)
    .create();

NOTE: you can use any number of the Modifier constants to “excludeFieldsWithModifiers” method. For example:

Gson gson = new GsonBuilder()
    .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
    .create();
####Gson‘s @Expose

This feature provides a way where you can mark certain fields of your objects to be excluded for consideration for serialization and deserialization to JSON. To use this annotation, you must create Gson by using new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(). The Gson instance created will exclude all fields in a class that are not marked with @Expose annotation.

User Defined Exclusion Strategies

If the above mechanisms for excluding fields and class type do not work for you then you can always write your own exclusion strategy and plug it into Gson. See the ExclusionStrategy JavaDoc for more information.

The following example shows how to exclude fields marked with a specific “@Foo” annotation and excludes top-level types (or declared field type) of class String.

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.FIELD})
  public @interface Foo {
    // Field tag only annotation
  }

  public class SampleObjectForTest {
    @Foo private final int annotatedField;
    private final String stringField;
    private final long longField;
    private final Class<?> clazzField;

    public SampleObjectForTest() {
      annotatedField = 5;
      stringField = "someDefaultValue";
      longField = 1234;
    }
  }

  public class MyExclusionStrategy implements ExclusionStrategy {
    private final Class<?> typeToSkip;

    private MyExclusionStrategy(Class<?> typeToSkip) {
      this.typeToSkip = typeToSkip;
    }

    public boolean shouldSkipClass(Class<?> clazz) {
      return (clazz == typeToSkip);
    }

    public boolean shouldSkipField(FieldAttributes f) {
      return f.getAnnotation(Foo.class) != null;
    }
  }

  public static void main(String[] args) {
    Gson gson = new GsonBuilder()
        .setExclusionStrategies(new MyExclusionStrategy(String.class))
        .serializeNulls()
        .create();
    SampleObjectForTest src = new SampleObjectForTest();
    String json = gson.toJson(src);
    System.out.println(json);
  }

======== OUTPUT ========
{"longField":1234}

JSON Field Naming Support

Gson supports some pre-defined field naming policies to convert the standard Java field names (i.e. camel cased names starting with lower case — “sampleFieldNameInJava”) to a Json field name (i.e. sample_field_name_in_java or SampleFieldNameInJava). See the FieldNamingPolicy class for information on the pre-defined naming policies.

It also has an annotation based strategy to allows clients to define custom names on a per field basis. Note, that the annotation based strategy has field name validation which will raise “Runtime” exceptions if an invalid field name is provided as the annotation value.

The following is an example of how to use both Gson naming policy features:

private class SomeObject {
  @SerializedName("custom_naming") private final String someField;
  private final String someOtherField;

  public SomeObject(String a, String b) {
    this.someField = a;
    this.someOtherField = b;
  }
}

SomeObject someObject = new SomeObject("first", "second");
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
String jsonRepresentation = gson.toJson(someObject);
System.out.println(jsonRepresentation);

======== OUTPUT ========
{"custom_naming":"first","SomeOtherField":"second"}

If you have a need for custom naming policy (see this discussion), you can use the @SerializedName annotation.

Sharing State Across Custom Serializers and Deserializers

Sometimes you need to share state across custom serializers/deserializers (see this discussion). You can use the following three strategies to accomplish this:

Store shared state in static fields

Declare the serializer/deserializer as inner classes of a parent type, and use the instance fields of parent type to store shared state

Use Java ThreadLocal

1 and 2 are not thread-safe options, but 3 is.

Streaming

In addition Gson’s object model and data binding, you can use Gson to read from and write to a stream. You can also combine streaming and object model access to get the best of both approaches.

Issues in Designing Gson

See the Gson design document for a discussion of issues we faced while designing Gson. It also include a comparison of Gson with other Java libraries that can be used for Json conversion.

Future Enhancements to Gson

For the latest list of proposed enhancements or if you’d like to suggest new ones, see the Issues section under the project website.

时间: 2024-10-09 18:20:27

Google -gson 最全的文档的相关文章

变换文档主题风格+截图+全选文档+统一文档样式+删除空白页+书法字帖+稿纸格式

昨晚因为写博客结果把自己写兴奋了,都11点多了还困,然后有只猪就在那不停问我为啥这么兴奋,跟他说了原因还不信,真的好想打人,哼.算了,不跟这只猪计较了,谁让你是猪呢?猪毕竟可能听不懂人话,哈哈哈哈哈哈哈哈哈哈哈哈......不知道为什么,好怕猪看了后我会被打,O(∩_∩)O哈!毕竟我家猪头每天早上都叫我起床,这么暖的男朋友我还是不能吐槽太多的,今天早上打电话知道我还没起床跟我说了几句然后让我再睡会,恩,确实是要好好夸夸这个boy,猪头,有你真好!另外,上课........别走神了,飞机都快被你承

http://tool.oschina.net 在线API文档库java jquery ,php,很全的文档库

http://tool.oschina.net 1.6API文档(中文)的下载地址: ZIP格式:http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html_zh_CN.zip CHM格式:http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/chm/JDK_API_1_6_zh_CN.

五分钟轻松搞定产品需求文档!这可能史上最全PRD文档模板

本文由  @JustWu 原创发布于社区 为什么写这篇文章? 第一:写PMCAFF的PRD文档,大家都是用户,比较好参考与理解,方便大家来找我写的不好的地方. 第二:我在自学PRD文档的编写过程中,总是遇到PRD文档里的对应产品总是找不到或是下架的情况,很难找到比较全面以及详细的参考模板,故一气之下撸了一篇,写好分享之. 关于这篇文章: 1.PRD本来就没有固定的版式,根据团队以及个人的需求有所差别,本篇力求简单,不累述. 2.这篇PRD可以再写的详细些,因为怕内容太多阅读太麻烦,对于需求说明以

mt6762芯片资料(全)整理文档下载

mt6762设备(见图1-1),集成蓝牙.fm.wlan和gps模块,是一个高度集成的基带同时包含调制解调器和启用应用程序处理子系统lte/lte-a和c2k智能手机应用程序.该芯片集成了手臂Cortex-A53运行速度可达2.0千兆赫,强大的多标准视频编解器.元素铟的符号添加,大量的接口和连接外设包含在接口到相机,触摸屏显示器和mm/sd卡. 应用程序处理器,一个八度核心配置Coltex-a53mpcore tm的扶手霓虹灯发动机提供处理能力必须支持最新的开放像web这样的应用程序要求很高浏览

Spring security 3 非常全的文档 API 中文版

Spring Security 安全权限管理手册 序言 I. 基础篇 6.1. MD5加密 6.2. 盐值加密 6.3. 用户信息缓存 6.4. 获取当前用户信息 5.1. 数据库表结构 5.2. 初始化数据 5.3. 实现从数据库中读取资源信息 5.3.1. 需要何种数据格式 5.3.2. 替换原有功能的切入点 4.1. 实现自定义登陆页面 4.2. 修改配置文件 4.3. 登陆页面中的参数配置 4.4. 测试一下 3.1. 自定义表结构 3.2. 初始化数据 3.3. 获得自定义用户权限信息

朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素

朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素 [下载文本PDF进行阅读] 本文我会来说说我认为架构评审中应该看的一些点,以及我写设计文档的一些心得.助你在架构评审中过五关斩六将,助你写出能让人收藏点赞的设计文档. 技术架构评审 架构评审或技术方案评审的价值在于集众人的力量大家一起来分析看看方案里是否有坑,方案上线后是否会遇到不可逾越的重大技术问题,提前尽可能把一些事情先考虑到提出质疑其实对项目的健康发展有很大的好处.很多公司都有架构评审委员会都有架构评审的流程,做业务的兄弟要

第一次文档编写总结(机房收费系统)

从图中可以看出编写文档的顺序,从可行性研究报告到开发进度月报构成了机房收费系统的整体文档,贯穿了软件工程的整个生命周期. 第一次机房收费系统和软工视频的完成是编写文档的依据和基础.起初,是一种无从下手的感觉.首先我们应该清楚文档是指导我们开发的,是在代码开发之前写的,而不是开发之后写的.有了学生信息管理系统的基础,我们第一次机房收费系统只是尝试着去写代码完成要求的功能,而不是一次正规的开发.人力物力财力都没有系统正规地去考虑.开发前的分析设计.开发中的细节和开发后的维护我们都没有涉及到.因此,编

Android多媒体--MediaCodec 中文API文档

*由于工作需要,需要利用MediaCodec实现Playback及Transcode等功能,故在学习过程中翻译了Google官方的MediaCodec API文档,由于作者水平限制,文中难免有错误和不恰当之处,望批评指正. *转载请注明出处:http://www.cnblogs.com/roger-yu/ MediaCodec public final class MediaCodec extends Object Java.lang.Object → android.media.MediaCo

共克时艰,鸿翼免费为全国企业开放100G远程文档协作平台

2020年新冠疫情给全国企业带来了巨大的冲击,几乎企业都要通过远程协作办公方式应对疫情带来的延期复工,上海鸿翼软件技术股份有限公司(以下简称"鸿翼")现向全社会免费开放自主研发的"InDrive协同企业云盘"平台,与全国企业同心协力,共克时艰. InDrive协同企业云盘是平台基于企业团队分配云盘空间,可助力企业实现远程在线的文档存储.管理.编辑等远程团队协作,支持多终端访问,为用户提供高效.安全的在线办公协作平台. 团队协作用户可免费注册并申请创建企业团队,并通过