加载中…
个人资料
喜之郎
喜之郎
  • 博客等级:
  • 博客积分:0
  • 博客访问:741
  • 关注人气:12
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Gson 对 Map 嵌套类型的序列化与反序列化

(2013-11-04 15:20:11)
分类: JSON

Gson 对 Map  嵌套类型的序列化与反序列化

gson 简介:

Gson is a Java library that can be used to convert Java Objects into its JSON representation

gson 扩展的一种方式:通过com.google.gson.GsonBuilder 注册TypeAdapter:

demo code:

 

[java] view plaincopy
  1. import java.io.Serializable;  
  2. import java.lang.reflect.Type;  
  3. import java.text.DateFormat;  
  4. import com.google.gson.FieldNamingPolicy;  
  5. import com.google.gson.Gson;  
  6. import com.google.gson.GsonBuilder;  
  7. import com.google.gson.JsonDeserializationContext;  
  8. import com.google.gson.JsonDeserializer;  
  9. import com.google.gson.JsonElement;  
  10. import com.google.gson.JsonParseException;  
  11. import com.google.gson.JsonSerializationContext 
  12. import com.google.gson.JsonSerializer;  
  13. public class Demo  
  14.     public Demo(){  
  15.          Gson gson new GsonBuilder()  
  16.              .registerTypeAdapter(Id.classnew IdTypeAdapter())  
  17.              .serializeNulls()  
  18.              .setDateFormat(DateFormat.LONG)  
  19.              .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)  
  20.              .setPrettyPrinting()  
  21.              .setVersion(1.0 
  22.              .create();  
  23.          Id id new Id();  
  24.          gson.toJson(id, Id.class);  
  25.      
  26.       
  27.     public static class Id implements Serializable{  
  28.         private static final long serialVersionUID -7698012176465651638L;  
  29.           
  30.      
  31.       
  32.     public static class IdTypeAdapter implements JsonSerializer, JsonDeserializer  
  33.         @Override  
  34.         public JsonElement serialize(Id src, Type typeOfSrc,  
  35.                 JsonSerializationContext context)  
  36.             //TODO serialize id type here  
  37.             return null 
  38.          
  39.         @Override  
  40.         public Id deserialize(JsonElement json, Type typeOfT,  
  41.                 JsonDeserializationContext context) throws JsonParseException  
  42.             // TODO deserialize Id type here  
  43.             return null 
  44.          
  45.           
  46.      
  47.  

 

遇到的问题:

      遇到这样的情况,对于现有的随机的数据(数据格式无法确定,类型复杂),需要使用 Map 类型于json格式互相转换,其中Map中的Object类型的value可能会是Map.现有的gson版本会遇到 无法序列化或者无法反序列化,因为gson是通过Map 去确定value的类型为Object.class,无法进一步序列化。

 

改进:

      照猫画虎,扩展现有的com.google.gson.DefaultTypeAdapters.MapTypeAdapter(此类为package visible, 要么copy代码,要么让自己的package为com.google.gson)

代码demo:

 

 

[java] view plaincopy
  1. package com.google.gson;  
  2. import java.lang.reflect.Type;  
  3. import java.util.Map;  
  4. import java.util.Set;  
  5. import com.google.gson.DefaultTypeAdapters.MapTypeAdapter;  
  6. public class FixedMapTypeAdapter extends MapTypeAdapter  
  7.     @SuppressWarnings("unchecked" 
  8.     @Override  
  9.     public JsonElement serialize(Map src, Type typeOfSrc,  
  10.             JsonSerializationContext context)  
  11.         JsonObject map new JsonObject();  
  12.         for (Map.Entry entry (Set) src.entrySet())  
  13.             Object value entry.getValue();  
  14.             JsonElement valueElement;  
  15.             if (value == null 
  16.                 valueElement JsonNull.createJsonNull();  
  17.             else  
  18.                 Type childType value.getClass();  
  19.                 valueElement context.serialize(value, childType);  
  20.              
  21.             map.add(String.valueOf(entry.getKey()), valueElement);  
  22.          
  23.         return map;  
  24.      
  25.     @SuppressWarnings("unchecked" 
  26.     @Override  
  27.     public Map deserialize(JsonElement json, Type typeOfT,  
  28.             JsonDeserializationContext context) throws JsonParseException  
  29.         // Use ObjectConstructor to create instance instead of hard-coding a  
  30.         // specific type.  
  31.         // This handles cases where users are using their own subclass of Map.  
  32.         Map map constructMapType(typeOfT, context);  
  33.         TypeInfoMap mapTypeInfo new TypeInfoMap(typeOfT);  
  34.         for (Map.Entry entry json.getAsJsonObject()  
  35.                 .entrySet())  
  36.             Object key context.deserialize(new JsonPrimitive(entry.getKey()),  
  37.                     mapTypeInfo.getKeyType());  
  38.             JsonElement jsonElement entry.getValue();  
  39.             String jsonValue jsonElement.toString();  
  40.             Type valueType mapTypeInfo.getValueType();  
  41.             if(jsonValue.startsWith("{")){  
  42.                 valueType new ParameterizedTypeImpl(Map.classnew Type[]{String.classObject.class}, null);  
  43.              
  44.             Object value context.deserialize(jsonElement, valueType);  
  45.             map.put(key, value);  
  46.          
  47.         return map;  
  48.      
  49.     @SuppressWarnings("unchecked" 
  50.     private Map constructMapType(Type mapType,  
  51.             JsonDeserializationContext context)  
  52.         JsonDeserializationContextDefault contextImpl (JsonDeserializationContextDefault) context;  
  53.         ObjectConstructor objectConstructor contextImpl  
  54.                 .getObjectConstructor();  
  55.         return (Map) objectConstructor.construct(mapType);  
  56.      

 

使用方式:

 

[java] view plaincopy
  1. private final Gson gson new GsonBuilder().registerTypeAdapter(Map.classnew FixedMapTypeAdapter()).create();  

局限:

      这样仅仅解决了gson对于嵌套的Map类型的序列化与反序列化,并且要求Map中的value为primative type or

Map(代码42行,使用“{”作为判断是否为complex value type)

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有