JSON知识总结- Gson(三)

1.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.class object 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<Bar>, 
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 fooType actually defines an anonymous local inner class containing a method getType() that returns the fully parameterized type. 

2.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;
  }
}

解决方法:

Option 1: Use Gson's parser API (low-level streaming parser or the DOM parser JsonParser) to parse the array elements and then  use Gson.fromJson() on each of the array elements.This is the preferred approach.Here is an example that demonstrates how to do this.

/*
 * Copyright (C) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.gson.extras.examples.rawcollections;

import java.util.ArrayList;
import java.util.Collection;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;

public class RawCollectionsExample {
	static class Event {
		private String name;
		private String source;

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

		@Override
		public String toString() {
			return String.format("(name=%s, source=%s)", name, source);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void main(String[] args) {
		Gson gson = new Gson();
		Collection collection = new ArrayList();
		collection.add("hello");
		collection.add(5);
		collection.add(new Event("GREETINGS", "guest"));
		String json = gson.toJson(collection);
		System.out.println("Using Gson.toJson() on a raw collection: " + json);

                JsonParser parser = new JsonParser();
		JsonArray array = parser.parse(json).getAsJsonArray();
		String message = gson.fromJson(array.get(0), String.class);
		int number = gson.fromJson(array.get(1), int.class);
		Event event = gson.fromJson(array.get(2), Event.class);
		System.out.printf("Using Gson.fromJson() to get: %s, %d, %s", message,
				number, event);
	}
}
Option 2: Register a type adapter for Collection.class that looks at each of the array members and maps them to appropriate objects. The disadvantage of this approach is that it will screw up deserialization of other collection types in Gson.

Option 3: Register a type adapter for MyCollectionMemberType and use fromJson with Collection<MyCollectionMemberType>
This approach is practical only if the array appears as a top-level element or if you can change the field type holding the collection to be of type Collection<MyCollectionMemberType>.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值