FastJson扩展 -- 支持多态 fastjson扩展——多态支持

fastjson扩展——多态支持

               fastjson在从json字符串解析成对象的时候是不支持多态的。

               什么意思呢?就是说我调用JSON.parseObject(jsonstr, XXX.class)方法的时候,如果XXX是一个抽象类,或者接口,我是没有办法根据json字符串中提供的实现类信息解析成相应的实现类的。这样调用后的结果是null。

               如何做到对多态的支持呢?我们先要研究一下fastjson的源码。我做的扩展是基于最新版本fastjson-1.1.28.jar进行的。

      源码分析

        解析的类从JSON转交给DefaultJSONParser

              我们调用JSON.parseObject(jsonstr, XXX.class)方法的时候,最后会调用一个parseObject(String input, Type clazz, ParserConfig config, int featureValues, Feature... features)方法。在这个方法中,关键是实例化了一个DefaultJSONParser实例,这个是解析的关键。调用的是parser.parseObject(clazz)。

[java]  view plain  copy
  1. public static final <T> T parseObject(String text, Class<T> clazz) {  
  2.              //feature可以new Feature[0]这样生成               
  3.              return parseObject(text, clazz, new Feature[0]);  
  4.     }  

[java]  view plain  copy
  1. public static final <T> T parseObject(String text, Class<T> clazz,  
  2.             Feature... features) {  
  3.               //最终调用的是该方法  
  4.               return (T) parseObject(text, (Type) clazz,  
  5.                 ParserConfig.getGlobalInstance(), DEFAULT_PARSER_FEATURE,  
  6.                 features);  
  7.     }  

[java]  view plain  copy
  1. public static final <T> T parseObject(String input, Type clazz,  
  2.             ParserConfig config, int featureValues, Feature... features) {  
  3.         if (input == null) {  
  4.             return null;  
  5.         }  
  6.   
  7.         for (Feature featrue : features) {  
  8.             featureValues = Feature.config(featureValues, featrue, true);  
  9.         }  
  10.   
  11.                 //解析工作转交给DefaultJSONParser  
  12.         DefaultJSONParser parser = new DefaultJSONParser(input, config,  
  13.                 featureValues);  
  14.         T value = (T) parser.parseObject(clazz);  
  15.   
  16.         handleResovleTask(parser, value);  
  17.   
  18.         parser.close();  
  19.   
  20.         return (T) value;  
  21.     }  

         解析的真正工作者,各种Deserializer

               在DefaultJSONParser的parseObject中,通过ParserConfig去获得相应的反序列化类,并通过反序列化类去反序列化出我们需要解析的对象。

[java]  view plain  copy
  1. public <T> T parseObject(Type type) {  
  2.         if (lexer.token() == JSONToken.NULL) {  
  3.             lexer.nextToken();  
  4.             return null;  
  5.         }  
  6.   
  7.         //通过ParserConfig去获得反序列化工具类  
  8.         ObjectDeserializer derializer = config.getDeserializer(type);  
  9.   
  10.         try {  
  11.           //通过反序列化工具类解析出我们需要的对象  
  12.           return (T) derializer.deserialze(this, type, null);  
  13.         } catch (JSONException e) {  
  14.             throw e;  
  15.         } catch (Throwable e) {  
  16.             throw new JSONException(e.getMessage(), e);  
  17.         }  
  18.     }  

         ParserConfig是如何管理Deserializer的

           常用类的Deserializer保存在IdentityHashMap之中

               我们先从ParserConfig的构造器看起,其中向类型为HashSet<Class<?>>的primitiveClasses成员变量添加了各种常用类。向类型为IdentityHashMap<Type, ObjectDeserializer>的derializers成员变量绑定常用类的Deserializer。

               

[java]  view plain  copy
  1. private final Set<Class<?>> primitiveClasses  = new HashSet<Class<?>>();  
  2.   
  3. private final IdentityHashMap<Type, ObjectDeserializer> derializers  = new IdentityHashMap<Type, ObjectDeserializer>();  
  4.   
  5. public ParserConfig(){  
  6.         primitiveClasses.add(boolean.class);  
  7.         primitiveClasses.add(Boolean.class);  
  8.   
  9.         primitiveClasses.add(char.class);  
  10.         primitiveClasses.add(Character.class);  
  11.   
  12.         primitiveClasses.add(byte.class);  
  13.         primitiveClasses.add(Byte.class);  
  14.   
  15.         primitiveClasses.add(short.class);  
  16.         primitiveClasses.add(Short.class);  
  17.   
  18.         primitiveClasses.add(int.class);  
  19.         primitiveClasses.add(Integer.class);  
  20.   
  21.         primitiveClasses.add(long.class);  
  22.         primitiveClasses.add(Long.class);  
  23.   
  24.         primitiveClasses.add(float.class);  
  25.         primitiveClasses.add(Float.class);  
  26.   
  27.         primitiveClasses.add(double.class);  
  28.         primitiveClasses.add(Double.class);  
  29.   
  30.         primitiveClasses.add(BigInteger.class);  
  31.         primitiveClasses.add(BigDecimal.class);  
  32.   
  33.         primitiveClasses.add(String.class);  
  34.         primitiveClasses.add(java.util.Date.class);  
  35.         primitiveClasses.add(java.sql.Date.class);  
  36.         primitiveClasses.add(java.sql.Time.class);  
  37.         primitiveClasses.add(java.sql.Timestamp.class);  
  38.   
  39.         derializers.put(SimpleDateFormat.class, DateFormatDeserializer.instance);  
  40.         derializers.put(java.sql.Timestamp.class, TimestampDeserializer.instance);  
  41.         derializers.put(java.sql.Date.class, SqlDateDeserializer.instance);  
  42.         derializers.put(java.sql.Time.class, TimeDeserializer.instance);  
  43.         derializers.put(java.util.Date.class, DateDeserializer.instance);  
  44.         derializers.put(Calendar.class, CalendarDeserializer.instance);  
  45.   
  46.         derializers.put(JSONObject.class, JSONObjectDeserializer.instance);  
  47.         derializers.put(JSONArray.class, JSONArrayDeserializer.instance);  
  48.   
  49.         derializers.put(Map.class, MapDeserializer.instance);  
  50.         derializers.put(HashMap.class, MapDeserializer.instance);  
  51.         derializers.put(LinkedHashMap.class, MapDeserializer.instance);  
  52.         derializers.put(TreeMap.class, MapDeserializer.instance);  
  53.         derializers.put(ConcurrentMap.class, MapDeserializer.instance);  
  54.         derializers.put(ConcurrentHashMap.class, MapDeserializer.instance);  
  55.   
  56.         derializers.put(Collection.class, CollectionDeserializer.instance);  
  57.         derializers.put(List.class, CollectionDeserializer.instance);  
  58.         derializers.put(ArrayList.class, CollectionDeserializer.instance);  
  59.   
  60.         derializers.put(Object.class, JavaObjectDeserializer.instance);  
  61.         derializers.put(String.class, StringDeserializer.instance);  
  62.         derializers.put(char.class, CharacterDeserializer.instance);  
  63.         derializers.put(Character.class, CharacterDeserializer.instance);  
  64.         derializers.put(byte.class, NumberDeserializer.instance);  
  65.         derializers.put(Byte.class, NumberDeserializer.instance);  
  66.         derializers.put(short.class, NumberDeserializer.instance);  
  67.         derializers.put(Short.class, NumberDeserializer.instance);  
  68.         derializers.put(int.class, IntegerDeserializer.instance);  
  69.         derializers.put(Integer.class, IntegerDeserializer.instance);  
  70.         derializers.put(long.class, LongDeserializer.instance);  
  71.         derializers.put(Long.class, LongDeserializer.instance);  
  72.         derializers.put(BigInteger.class, BigIntegerDeserializer.instance);  
  73.         derializers.put(BigDecimal.class, BigDecimalDeserializer.instance);  
  74.         derializers.put(float.class, FloatDeserializer.instance);  
  75.         derializers.put(Float.class, FloatDeserializer.instance);  
  76.         derializers.put(double.class, NumberDeserializer.instance);  
  77.         derializers.put(Double.class, NumberDeserializer.instance);  
  78.         derializers.put(boolean.class, BooleanDeserializer.instance);  
  79.         derializers.put(Boolean.class, BooleanDeserializer.instance);  
  80.         derializers.put(Class.class, ClassDerializer.instance);  
  81.         derializers.put(char[].class, CharArrayDeserializer.instance);  
  82.   
  83.         derializers.put(UUID.class, UUIDDeserializer.instance);  
  84.         derializers.put(TimeZone.class, TimeZoneDeserializer.instance);  
  85.         derializers.put(Locale.class, LocaleDeserializer.instance);  
  86.         derializers.put(InetAddress.class, InetAddressDeserializer.instance);  
  87.         derializers.put(Inet4Address.class, InetAddressDeserializer.instance);  
  88.         derializers.put(Inet6Address.class, InetAddressDeserializer.instance);  
  89.         derializers.put(InetSocketAddress.class, InetSocketAddressDeserializer.instance);  
  90.         derializers.put(File.class, FileDeserializer.instance);  
  91.         derializers.put(URI.class, URIDeserializer.instance);  
  92.         derializers.put(URL.class, URLDeserializer.instance);  
  93.         derializers.put(Pattern.class, PatternDeserializer.instance);  
  94.         derializers.put(Charset.class, CharsetDeserializer.instance);  
  95.         derializers.put(Number.class, NumberDeserializer.instance);  
  96.         derializers.put(AtomicIntegerArray.class, AtomicIntegerArrayDeserializer.instance);  
  97.         derializers.put(AtomicLongArray.class, AtomicLongArrayDeserializer.instance);  
  98.         derializers.put(StackTraceElement.class, StackTraceElementDeserializer.instance);  
  99.   
  100.         derializers.put(Serializable.class, defaultSerializer);  
  101.         derializers.put(Cloneable.class, defaultSerializer);  
  102.         derializers.put(Comparable.class, defaultSerializer);  
  103.         derializers.put(Closeable.class, defaultSerializer);  
  104.   
  105.         try {  
  106.             derializers.put(Class.forName("java.awt.Point"), PointDeserializer.instance);  
  107.             derializers.put(Class.forName("java.awt.Font"), FontDeserializer.instance);  
  108.             derializers.put(Class.forName("java.awt.Rectangle"), RectangleDeserializer.instance);  
  109.             derializers.put(Class.forName("java.awt.Color"), ColorDeserializer.instance);  
  110.         } catch (Throwable e) {  
  111.             // skip  
  112.         }  
  113.     }  

            自己实现的类的Deserializer是JavaBeanDeserializer

               在getDeserializer的方法中,首先从derializers中取寻找是否有相应的反序列化工具类,对于常用类,在这个时候就能找到相应的反序列化工具类。如果是自己实现的类,最终获得的反序列化工具为JavaBeanDeserializer

[java]  view plain  copy
  1. public ObjectDeserializer getDeserializer(Type type) {  
  2.         //去map中需找,如果找到为重用类  
  3.         ObjectDeserializer derializer = this.derializers.get(type);  
  4.         if (derializer != null) {  
  5.             return derializer;  
  6.         }  
  7.   
  8.         if (type instanceof Class<?>) {  
  9.             //不是常用类  
  10.             return getDeserializer((Class<?>) type, type);  
  11.         }  
  12.   
  13.         省略  
  14.   
  15. }  
[java]  view plain  copy
  1. public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {  
  2.   
  3.         省略  
  4.   
  5.         derializer = createJavaBeanDeserializer(clazz, type);  
  6.   
  7. }  

         createJavaBeanDeserializer根据实际情况通过asm或者构造器实例化JavaBeanDeserializer

               其中有个asmEnable成员变量表示是否通过asm进行实例化。默认android是不通过asm进行实例化的。

[java]  view plain  copy
  1. private boolean asmEnable = !ASMUtils.isAndroid();  
  2.   
  3. public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {  
  4.   
  5.        省略  
  6.   
  7.        if (!asmEnable) {  
  8.             return new JavaBeanDeserializer(this, clazz, type);  
  9.         }  
  10.   
  11.        return ASMDeserializerFactory.getInstance().createJavaBeanDeserializer(this, clazz, type);  
  12.   
  13. }  

          JavaBeanDeserializer的构造器通过DeserializeBeanInfo.computeSetters获得解析类的构造器

                 JavaBeanDeserializer有个私有的,没有setter的成员变量beanInfo,解析类的构造器保存在该成员变量中

[java]  view plain  copy
  1. public JavaBeanDeserializer(ParserConfig config, Class<?> clazz, Type type){  
  2.         this.clazz = clazz;  
  3.         this.type = type;  
  4.   
  5.         //beanInfo中包含了构造器,这就是为什么能解析出对象  
  6.         beanInfo = DeserializeBeanInfo.computeSetters(clazz, type);  
  7.   
  8.         for (FieldInfo fieldInfo : beanInfo.getFieldList()) {  
  9.             addFieldDeserializer(config, clazz, fieldInfo);  
  10.         }  
  11.     }  

[java]  view plain  copy
  1. public static DeserializeBeanInfo computeSetters(Class<?> clazz, Type type) {  
  2.         DeserializeBeanInfo beanInfo = new DeserializeBeanInfo(clazz);  
  3.           
  4.         //获取构造器  
  5.         Constructor<?> defaultConstructor = getDefaultConstructor(clazz);  
  6.   
  7.         省略  
  8. }  

[java]  view plain  copy
  1. public static Constructor<?> getDefaultConstructor(Class<?> clazz) {  
  2.         //如果是抽象类或接口,这里返回null,这就是fastjson不支持多态的原因  
  3.         if (Modifier.isAbstract(clazz.getModifiers())) {  
  4.             return null;  
  5.         }  
  6.   
  7.         //不是抽象类或接口,通过反射获得构造器  
  8.         Constructor<?> defaultConstructor = null;  
  9.         for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {  
  10.             if (constructor.getParameterTypes().length == 0) {  
  11.                 defaultConstructor = constructor;  
  12.                 break;  
  13.             }  
  14.         }  
  15.   
  16.         省略  
  17. }  
                   

          JavaBeanDeserializer的解析json字符串的过程,调用public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName)方法

                 JavaBeanDeserializer实际的解析json字符串是通过调用deserialze方法进行的。其中就是通过算法解析json字符串而已。这里就不上源码了,值得说的是parser中包含了原始的json字符串。type是解析的类,可能是抽象类或接口。

                 

       思路与实现

                 源码看明白后,思路就很清晰了。

          1、实现一个Deserializer,继承自JavaBeanDeserializer,在deserialze方法中解析出json字符串中表明的实现类,并把type变量从抽象类或接口替换成实现类。再将实现类的type传入父类的deserialze方法中。需要注意的是,在构造器中DeserializeBeanInfo.computeSetters已经把beanInfo作为抽象类或接口了,因此需要替换type后再计算一次,并替换原来的beanInfo成员变量。

          2、如何比较json字符串中的实现类信息和接口或抽象类中指定的实现类信息,可以有很多办法,我这里通过注释(Annotation)的方式。

          3、为了获得我们自定义的Deserializer,需要实现一个ParserConfig类,该类继承自ParserConfig类,重写

getDeserializer方法。

          4、哪些类需要通过我们的Deserializer呢,我的做法是创建了一个空的接口,一旦目标类实现了这个接口,在getDeserialize方法中就获得我们自己实现的Deserializer。


                接下来,看一下实现代码。两个注释类JsonMaps和JsonMap用来标注json字符串中的实现类信息对应的class name

[java]  view plain  copy
  1. /** 
  2.  *  
  3.  * fastjson扩展,解析多态时申明实现的类 
  4.  *  
  5.  * @author 吴林峰 
  6.  * 
  7.  */  
  8. @Target({ElementType.TYPE})  
  9. @Retention(RetentionPolicy.RUNTIME)  
  10. public @interface JsonMaps {  
  11.   
  12.     JsonMap[] values();  
  13.       
  14. }  

[java]  view plain  copy
  1. /** 
  2.  *  
  3.  * fastjson扩展,申明具体的实现类 
  4.  *  
  5.  * @author 吴林峰 
  6.  * 
  7.  */  
  8. @Target({ElementType.TYPE})  
  9. @Retention(RetentionPolicy.RUNTIME)  
  10. public @interface JsonMap {  
  11.   
  12.     String key();  
  13.       
  14.     Class<?> value();  
  15.       
  16. }  

               表明需要多态解析的接口

[java]  view plain  copy
  1. /** 
  2.  *  
  3.  * fastjson,支持多态的标志,为一个空的接口,需要多态解析json的类需要实现该接口 
  4.  *  
  5.  * @author 吴林峰 
  6.  * 
  7.  */  
  8. public interface FastJsonPolymorphism {  
  9.   
  10. }  

                自定义ParserConfig

[java]  view plain  copy
  1. /** 
  2.  *  
  3.  * 扩展fastjson,支持多态的解析 
  4.  *  
  5.  * @author 吴林峰 
  6.  * 
  7.  */  
  8. public class PolymorphismParserConfig extends ParserConfig{  
  9.       
  10.     public PolymorphismParserConfig(){  
  11.         super();  
  12.     }  
  13.       
  14.     @Override  
  15.     public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {  
  16.                 //实现了空的接口,表明需要多态解析  
  17.                 if(clazz==FastJsonPolymorphism.class){  
  18.                       //返回我们自定义的多态反序列化工具,直接通过构造器,没有用asm  
  19.                       return new PolymorphismDeserializer(this, clazz, type);   
  20.         }  
  21.                 return super.getDeserializer(clazz, type);  
  22.     }  
  23.       
  24. }  

                自定义的多态反序列化工具类

[java]  view plain  copy
  1. /** 
  2.  *  
  3.  * 扩展fastjson,对多态支持 
  4.  * 目前缺陷,调用了两次bean信息计算DeserializeBeanInfo.computeSetters 
  5.  *  
  6.  * @author 吴林峰 
  7.  * 
  8.  */  
  9. public class PolymorphismDeserializer extends JavaBeanDeserializer{  
  10.   
  11.     private static final Logger logger = LoggerFactory.getLogger(PolymorphismDeserializer.class);  
  12.       
  13.     private static final String TARGET_FIELD="objClass";  
  14.     private static final String TYPE_NAME_PREFIX = "class ";  
  15.     private static final String JAVA_BEAN_DESERIALIZER_BEANINFO_FIELD="beanInfo";  
  16.       
  17.     public PolymorphismDeserializer(DeserializeBeanInfo beanInfo){  
  18.        super(beanInfo);  
  19.     }  
  20.   
  21.     public PolymorphismDeserializer(ParserConfig config, Class<?> clazz) {  
  22.        super(config, clazz);  
  23.     }  
  24.   
  25.     public PolymorphismDeserializer(ParserConfig config, Class<?> clazz, Type type) {  
  26.        super(config,clazz,type);  
  27.     }  
  28.   
  29.     @Override  
  30.     public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName){  
  31.         String jsonstr=parser.getInput();  
  32.         Optional<String> targetKey=Optional.ofNullable(parseTarget(jsonstr));  
  33.         if(targetKey.isPresent()){  
  34.             logger.debug("目标类的key:"+targetKey.get());  
  35.             String className = type.toString();  
  36.              if (className.startsWith(TYPE_NAME_PREFIX)) {  
  37.                  className = className.substring(TYPE_NAME_PREFIX.length());  
  38.              }  
  39.              try {  
  40.                 //解析实际类  
  41.                 Class<?> clazz=Class.forName(className);  
  42.                 if(clazz.isAnnotationPresent(JsonMaps.class)){  
  43.                     JsonMaps jsonMaps=clazz.getAnnotation(JsonMaps.class);  
  44.                     JsonMap[] js=jsonMaps.values();  
  45.                     boolean flag=false;  
  46.                     for(JsonMap j : js){  
  47.                      if(targetKey.get().equals(j.key())){  
  48.                          Class<?> target=j.value();  
  49.                          logger.debug("目标类:"+target.getName());  
  50.                          logger.debug("modifier:"+Modifier.toString(target.getModifiers()));  
  51.                          type=(Type) target;  
  52.                            
  53.                          //由于config中getDeserializer方法中,调用JavaBeanDeserializer时已经把抽象类或接口的信息计算了,这里需要替换成实现类的信息  
  54.                          DeserializeBeanInfo beanInfo=DeserializeBeanInfo.computeSetters(target, type);   
  55.                          //由于JavaBeanDeserializer中的beanInfo字段为private并且没有setter,只能通过反射设置   
  56.                          Field beanInfoField=JavaBeanDeserializer.class.getDeclaredField(JAVA_BEAN_DESERIALIZER_BEANINFO_FIELD);  
  57.                          beanInfoField.setAccessible(true);  
  58.                          beanInfoField.set(this, beanInfo);  
  59.                          flag=true;  
  60.                          break;  
  61.                       }  
  62.                     }  
  63.                     if(!flag){  
  64.                         logger.error("没有找到指定的类");  
  65.                         throw new NotFoundJsonMapClassException(targetKey.get());  
  66.                     }  
  67.                 }else{  
  68.                     logger.error("没有指定JsonMaps");  
  69.                     throw new NotFoundJsonMapsException(type.getTypeName());  
  70.                 }  
  71.             } catch (ClassNotFoundException e) {  
  72.                 e.printStackTrace();  
  73.             } catch (NoSuchFieldException e) {  
  74.                 e.printStackTrace();  
  75.             } catch (SecurityException e) {  
  76.                 e.printStackTrace();  
  77.             } catch (IllegalArgumentException e) {  
  78.                 e.printStackTrace();  
  79.             } catch (IllegalAccessException e) {  
  80.                 e.printStackTrace();  
  81.             }  
  82.         }else{  
  83.             logger.error("没有指定key");  
  84.             throw new NotFoundKeyException(jsonstr);  
  85.         }  
  86.         return super.deserialze(parser, type, fieldName);  
  87.     }  
  88.       
  89.     private String parseTarget(String jsonstr){  
  90.         String[] ts=jsonstr.split("\""+TARGET_FIELD+"\":");  
  91.         return Optional.ofNullable(ts[1])  
  92.                        .orElse("")  
  93.                        .split("\"|\"")[1];  
  94.     }  
  95.       
  96. }  

      demo

              假定json字符串如下:{"infoCnt":4,"objClass":"posList","period":15}

             objClass为指定实现类的别名。

             抽象类

[java]  view plain  copy
  1. @JsonMaps(values={  
  2.     @JsonMap(key="msg",value=SocketTXSQ.class),  
  3.     @JsonMap(key="posList",value=SocketARPL.class),  
  4.     @JsonMap(key="pars",value=SocketPARS.class),  
  5.     @JsonMap(key="fki",value=SocketFKI.class),  
  6.     @JsonMap(key="ici",value=SocketICI.class)  
  7. })  
  8. public abstract class SocketEntity implements FastJsonPolymorphism{  
  9.   
  10.         private int infoCnt;  
  11.         private int period;  
  12.   
  13.         public abstract void save(ApplicationContext ctx);  
  14.   
  15.         public int getPeriod() {  
  16.             return period;  
  17.         }  
  18.   
  19.         public void setPeriod(int period) {  
  20.             this.period = period;  
  21.         }  
  22.   
  23.         public int getInfoCnt() {  
  24.             return infoCnt;  
  25.         }  
  26.   
  27.         public void setInfoCnt(int infoCnt) {  
  28.            this.infoCnt = infoCnt;  
  29.         }  
  30.   
  31. }  

              实现类有5个

[java]  view plain  copy
  1. public class SocketARPL extends SocketEntity {  
  2.   
  3.          public void save(ApplicationContext ctx){  
  4.              System.out.println("实现类posList的save方法");  
  5.          }  
  6.   
  7. }  

[java]  view plain  copy
  1. public class SocketTXSQ extends SocketEntity {  
  2.   
  3.          public void save(ApplicationContext ctx){  
  4.              System.out.println("实现类msg的save方法");  
  5.          }  
  6.   
  7. }  

[java]  view plain  copy
  1. public class SocketPARS extends SocketEntity {  
  2.   
  3.          public void save(ApplicationContext ctx){  
  4.              System.out.println("实现类pars的save方法");  
  5.          }  
  6.   
  7. }  

[java]  view plain  copy
  1. public class SocketFKI extends SocketEntity {  
  2.   
  3.          public void save(ApplicationContext ctx){  
  4.              System.out.println("实现类fki的save方法");  
  5.          }  
  6.   
  7. }  

[java]  view plain  copy
  1. public class SocketICI extends SocketEntity {  
  2.   
  3.          public void save(ApplicationContext ctx){  
  4.              System.out.println("实现类ici的save方法");  
  5.          }  
  6.   
  7. }  

                 我们来看看调用fastjson解析json字符串获得的SocketEntity的结果如何:

[java]  view plain  copy
  1. //fastjson使用自带的ParserConfig解析抽象类SocketEntity,结果entity为null  
  2. SocketEntity entity = (SocketEntity) JSON.parseObject(str, SocketEntity.class);  
  3.   
  4. //fastjson通过我们实现的PolymorphismParserConfig解析抽象类SocketEntity,结果entity为SocketARPL类的实例  
  5. entity = (SocketEntity) JSON.parseObject(str, SocketEntity.classnew PolymorphismParserConfig(), JSON.DEFAULT_PARSER_FEATURE, new Feature[0]);  

                 如果json字符串改成{"infoCnt":4,"objClass":"msg","period":15},那么我们获得的对象为SocketTXSQ。实验表明,我们对fastjson的扩展成功,通过传入PolymorphismParserConfig就可以为抽象类或接口提供解析功能,返回我们期望的实现类的实例。

猜你喜欢

转载自blog.csdn.net/qq_29726869/article/details/80563894