标签:
上篇文章gson用户指南(上)翻译到了10、序列化和反序列化有任意类型对象的collection
我们继续
java.net.URL to match it with strings like "https://github.com/google/gson/" java.net.URI to match it with strings like "/google/gson/"你可以从源码中找到一些常用的类。例如JodaTime 点击打开链接
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调用检查类型适配器实现一个以上的接口,注册它。
private class DateTimeSerializer implements JsonSerializer<DateTime> {
public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toString());
}
}当它运行到一个DateTime对象序列化时。Gson会调用serialize()。private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return new DateTime(json.getAsJsonPrimitive().getAsString());
}
}当需要一个JSON字符串反序列化private class MoneyInstanceCreator implements InstanceCreator<Money> {
public Money createInstance(Type type) {
return new Money("1000000", CurrencyCode.USD);
}
}Type
可以是相应的泛型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();
}
}然而,有时你需要根据实际参数化类型创建实例。这种情况下,可以使用传递到createInstance方法的类型参数,例如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);
}
}在上面的示例中,如果没有传递参数化类型的真实类型,不能创建Id类的实例。我们通过方法参数传递类型type来解决这个问题。在本例中Java对象是类型参数化的类型表示的Id
< Foo >应该绑定到实例Id < Foo >。由于Id类只有一个参数化的类型参数T,我们使用getActualTypeArgument()返回的第0个元素类型的数组将持有Foo.classGson gson = new GsonBuilder().setPrettyPrinting().create(); String jsonOutput = gson.toJson(someObject);
Gson gson = new GsonBuilder().serializeNulls().create();注意,当使用Gson序列化null对象时,会在JsonElement 结构中增加JsonNull ,这个对象不能用于自定义序列化反序列化
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);输出{"s":null,"i":5}
null
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);{"newField":"new","field":"old"}
{"newerField":"newer","newField":"new","field":"old"}import java.lang.reflect.Modifier;
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC)
.create();可以添加多个常量Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
.create();
这个特性提供了一种方法,可以标记某些字段的对象排除序列化和反序列化为JSON。使用这个注解,必须调用new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()。这样@Expose注解的类和字段才能被序列化和反序列化。
如果排除字段和类类型上述机制不适合你,那么你可以编写自己的排斥战略,并把它应用到GSON。详细信息请参照文档,文档地址ExclusionStragegy
示例
@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);
}
{"longField":1234}Gson支持一些预先定义的字段命名策略转换标准的Java字段名,例如小写字母开头的驼峰式命名,详细信息可以参考文档FieldNamingPolicy
它也有一个基于注解的策略,允许客户端自定义名称。请注意,基于策略的注解有字段名的验证,如果一个无效的字段名称作为注解将增加运行异常。
下面是一个自定义命名策略的例子
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);
{"custom_naming":"first","SomeOtherField":"second"}http://groups.google.com/group/google-gson/browse_thread/thread/cb441a2d717f6892
http://google.github.io/gson/apidocs/com/google/gson/annotations/SerializedName.html
有时候需要共享序列化反序列化,可以用下面三个方法
(1)通过静态字段存储共享状态
(2)在父类中定义序列化反序列化内部类,并使用父类型的实例字段来存储共享状态。
(3)使用ThreadLocal
1,2是线程不安全的,3是线程安全的
除了Gson的对象模型和数据绑定,可使用GSON读取和写入流。也可以流和对象模型的访问都是用,以获得最佳的方法。
见GSON设计文档,对设计GSON时我们面临的问题进行了探讨。也包括GSON与可用于JSON的转换其他Java库的比较。
参考地址https://sites.google.com/site/gson/gson-design-document
标签:
原文地址:http://blog.csdn.net/robertcpp/article/details/51599124