Gson is one of the most commonly used libraries for JSON. Gson = new Gson(); Is created in this way. However, when I used a volley tool given by Muge recently, I couldn’t parse it out. I was very depressed. I looked for a long time and couldn’t find the reason. So let’s summarize how gson is used. Gson User Guide Google also has a Github page, ha ha, surprisingly 35 pages of open source project.

new Gson()

I’ve always done it this way… Gson has two important methods, one is toJson and the other is fromJson, which is serialization and deserialization. For example, parse this gson string:

{
    "name" : "Ravi Tamada"."email" : "[email protected]"."phone" : {
        "home" : "08947, 000000"."mobile" : "9999999999"}}Copy the code
Let's start with a Userpublic class User {
private String name;
private String email;
privatePhone phone; } let me write a Phonepublic class Phone {
private String home;
privateString mobile; } Everything is easy nownew Gson();
User user = gson.fromJson(response.toString(), User.class);
mTextViewVolley.setText(user.getName()+"\n"+user.getEmail()+"\n"+"phone:"+user.getPhone().getHome());
Copy the code

Examples of methods commonly used by Gson

Gson gson = new Gson();
/ / the serialization
MyObject myobj = new MyObject();  
String jsonstr = gson .toJson(myobj);
// deserialize
MyObject myobj = gson.fromJson(jsonstr, MyObject.class);  
// Serialize the array
String[] days = {"Sun"."Mon"."Tue"."Wed"."Thu"."Fri"."Sat"};
String numbersJson = gson.toJson(days);
// Serialize the collection
List<String> myobjs = new ArrayList<String>();
String jsonstr = gson.toJson(myobjs);
// Deserialize the collection array
List<MyObject> myobjs = gson.fromJson(str, new TypeToken<ArrayList<MyObject>>(){}.getType());
// Deserialization
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);
Copy the code

PS: If the class you want to convert includes generics, then you also need a TypeToken, from which you can get the specific type

annotations

Gson, however, is not that simple. He can also use annotations:

Expose

This annotation applies to the property to indicate that the property will be exposed to the Gson object when serialized and deserialized. This annotation only when creating Gson objects using GsonBuilder way to create and invoke the GsonBuilder. ExcludeFieldsWithoutExposeAnnotation () method is valid, otherwise is invalid. Here’s an example of how to use the @expose annotation:

publicclass User {@Expose privateString firstName;@Expose(serialize = false) privateString lastName;@Expose (serialize = false, deserialize = false) privateString emailAddress;private String password;
}
Copy the code

If you create a Gson object as new Gson(), the toJson() and fromJson() methods will manipulate these four properties during serialization and deserialization. However, if you use Gson Gson = new GsonBuilder () excludeFieldsWithoutExposeAnnotation (). The create () to create a Gson object, Gson’s toJson() and fromJson() methods will exclude the Password field because the password field is not marked with the @expose annotation. The Gson object also excludes the lastName and emailAddress fields because the @expose property serialize is set to false. Similarly, Gson will exclude the emailAddress field when deserializing because deserialize is set to false.

PS: If you do not want some attributes, you can also use transient mask, such as transient int val;

SerializedName

Used to change the name of the property after serialization to JSON. This annotation applies to the attribute, indicating that the attribute needs to serialize its name to the value specified in the annotation’s value attribute when serialized to Json. This annotation will override any FieldNamingPolicy, including the default naming policy. Here is an example of how the @serializedName annotation is used:

publicclass SomeClassWithFields {@SerializedName("name") privatefinal String someField;private finalString someOtherField;public SomeClassWithFields(String a, String b) {this.someField = a;this. SomeOtherField = b; }}Copy the code

{“name”:”a”,”someOtherField”:”b”}

Since

Use the @since annotation to maintain versioning. For example, if you have a REST API and have multiple versions of JSON, you can use it if fields are added to the next version of JSON, but you don’t want all versions to use these fields

publicclass Example33 {  
  publicstaticvoid main(String[] args) {  
    Gson gson = new GsonBuilder().setVersion(2.0).create();  
    String json = gson.toJson(new ExampleClass());  
    System.out.println("The Output for version 2.0...");  
    System.out.println(json);  
      
    gson= new GsonBuilder().setVersion(1.0).create();  
    json = gson.toJson(new ExampleClass());  
    System.out.println("\ nOutput for version 1.0...");  
    System.out.println(json);  
      
    gson= new Gson();  
    json = gson.toJson(new ExampleClass());  
    System.out.println("\nOutput for No version set..."); System.out.println(json); }}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";  
}  
Copy the code
Output: Output for version 2.0... {"field":"field","newField1":"field 1","newField2":"field 2"} Output for version 1.0... {"field":"field","newField1":"field 1"} Output for No version set... {"field":"field","newField1":"field 1","newField2":"field 2"}Copy the code

Until

In contrast to Since, it can be used if a field is removed from the next version of JSON, as above.

GsonBulider

After using the comments, we will create gson using GsonBuilder

Gson gson = new GsonBuilder()  
        .excludeFieldsWithoutExposeAnnotation() // Do not export attributes with @expose annotations in entities
        .enableComplexMapKeySerialization() // Support Map keys in the form of complex objects
        .setDateFormat("yyyy-MM-dd HH:mm:ss:SSS")// Time is converted to a specific format
        .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)Note: This does not apply to entities that use @serializedName annotations.
        .setPrettyPrinting() // Format the JSON result.
        .setVersion(1.0). DisableHtmlEscaping ()// GSON escapes HTML by default, but it can be set not to escape
        .serializeNulls(){a:null} {a:null} {a:null} {a:null}
        .create();
Copy the code

The generic

If the class you want to convert includes generics, then you also need TypeToken, which is used to get the concrete type

publicclass ApiResult<T> {
    privateint ret;
    private String msg;
    private T data;
    publicint getRet(a) {
        return ret;
    }
  publicvoid setRet(int ret) {
        this.ret = ret;
    }
  public String getMsg(a) {
        return msg;
    }
  publicvoid setMsg(String msg) {
        this.msg = msg;
    }
  public T getData(a) {
        return data;
    }
  publicvoid setData(T data) {
        this.data = data; }}Copy the code
ApiResult<UserInfo> r = GsonUtils.parse(json, new TypeToken<ApiResult<UserInfo>>() {}.getType());
Copy the code

Parsing JsonArray

I didn’t know Gson could parse JsonArray. So I used the following method

public static <T> List<T> readJsonArray(JSONArray array, Class<T> entityType){
        Gson gson =new Gson();
        List<T> list = new ArrayList<>();
        for(int i=0; i<array.length(); i++){try {
                T t = gson.fromJson(array.getJSONObject(i).toString(),entityType);
                list.add(t);
            } catch(JSONException e) { e.printStackTrace(); }}return list;
    }
Copy the code

Here is the gson User Guideu: Array Examples

Gson gson = new Gson();
int[] ints = {1.2.3.4.5};
String[] strings = {"abc"."def"."ghi"};

// Serialization
gson.toJson(ints);     / / = = > [1, 2, 3, 4, 5]
gson.toJson(strings);  // ==> ["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.
Copy the code

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
Copy the code

Fairly hideous: note how we define the type of collection. Unfortunately, there is no way to get around this in Java.

Collections Limitations

Can serialize collection of arbitrary objects but can not deserialize from it Because there is no way for the user to indicate the type of the resulting object While deserializing, Collection must be of a specific generic type All of this makes sense, and is rarely a problem when following good Java coding practices.