1

我已經遇到需要使用XStream 1.4.2反序列化可能是瞬態的字段。儘管如此,這些字段可能用@XStreamAlias@XStreamAsAttribute來註釋。是的,我知道,這聽起來很奇怪,這是一個糟糕的設計指標,但這是我目前所擁有的。由於XStream提供了一種指定自定義轉換器的方法,我試圖擴展com.thoughtworks.xstream.converters.reflection.ReflectionConverter以覆蓋省略所有試圖使XStream允許反序列化的瞬態字段的默認方式。然而,我完全堅持有兩個想法來實現這樣的轉換器,但它們都不起作用。因此,這裏是我的嘗試:使用XStream 1.4.2解串瞬態字段

首屆方式不起作用:

public final class TransientSimpleConverter extends ReflectionConverter { 

    private final Class<?> type; 

    private TransientSimpleConverter(Class<?> type, Mapper mapper, ReflectionProvider reflectionProvider) { 
     super(mapper, reflectionProvider); 
     this.type = type; 
    } 

    public static TransientSimpleConverter transientSimpleConverter(Class<?> type, XStream xStream) { 
     return new TransientSimpleConverter(type, xStream.getMapper(), xStream.getReflectionProvider()); 
    } 

    @Override 
    protected boolean shouldUnmarshalTransientFields() { 
     return true; 
    } 

    @Override 
    public boolean canConvert(Class type) { 
     return this.type == type; 
    } 

} 

第二屆方式不起作用或者:

public final class TransientComplexConverter extends ReflectionConverter { 

    private final Class<?> type; 

    private TransientComplexConverter(Class<?> type, Mapper mapper, ReflectionProvider provider) { 
     super(mapper, provider); 
     this.type = type; 
    } 

    public static TransientComplexConverter transientComplexConverter(Class<?> type, Mapper mapper, Iterable<String> fieldNames) { 
     return new TransientComplexConverter(type, mapper, TransientHackReflectionProvider.transientHackReflectionProvider(type, fieldNames)); 
    } 

    @Override 
    public boolean canConvert(Class type) { 
     return this.type == type; 
    } 

    private static final class TransientHackReflectionProvider extends PureJavaReflectionProvider { 

     private final Class<?> type; 
     private final Collection<Field> allowedFields; 
     private final Collection<String> allowedAliases; 

     private TransientHackReflectionProvider(Class<?> type, Collection<Field> allowedFields, Collection<String> allowedAliases) { 
      this.type = type; 
      this.allowedFields = allowedFields; 
      this.allowedAliases = allowedAliases; 
     } 

     public static TransientHackReflectionProvider transientHackReflectionProvider(final Class<?> type, Iterable<String> fieldNames) { 
      final Collection<Field> allowedFields = from(fieldNames).transform(new Function<String, Field>() { 
       @Override 
       public Field apply(String name) { 
        return field(type, name); 
       } 
      }).toList(); 
      final Collection<String> allowedAliases = transform(allowedFields, new Function<Field, String>() { 
       @Override 
       public String apply(Field f) { 
        return f.getName(); 
       } 
      }); 
      return new TransientHackReflectionProvider(type, allowedFields, allowedAliases); 
     } 

     @Override 
     protected boolean fieldModifiersSupported(Field field) { 
      return allowedFields.contains(field) ? true : super.fieldModifiersSupported(field); 
     } 

     @Override 
     public boolean fieldDefinedInClass(String fieldName, Class type) { 
      return type == this.type && allowedAliases.contains(fieldName) ? true : super.fieldDefinedInClass(fieldName, type); 
     } 

     private static final Field field(Class<?> type, String name) { 
      try { 
       final Field field = type.getDeclaredField(name); 
       checkArgument(isTransient(field.getModifiers()), name + " is not transient"); 
       checkArgument(field.getAnnotation(XStreamAsAttribute.class) != null, name + " must be annotated with XStreamAsAttribute"); 
       checkArgument(field.getAnnotation(XStreamAlias.class) != null, name + " must be annotated with XStreamAlias"); 
       return field; 
      } catch (final SecurityException ex) { 
       throw new RuntimeException(ex); 
      } catch (final NoSuchFieldException ex) { 
       throw new RuntimeException(ex); 
      } 
     } 

    } 

} 

任何建議或想法的解決方法嗎?提前致謝。

回答

0

我知道這個帖子已經過時了,但也許有人仍然感興趣。我的解決辦法:

XStream xstream = new XStream(new MyPureJavaReflectionProvider()); 

class MyPureJavaReflectionProvider extends PureJavaReflectionProvider { 

    public MyPureJavaReflectionProvider() { 
     this(new FieldDictionary(new ImmutableFieldKeySorter())); 
    } 

    public MyPureJavaReflectionProvider(FieldDictionary fieldDictionary) { 
     super(fieldDictionary); 
    } 

    protected boolean fieldModifiersSupported(Field field) { 
     int modifiers = field.getModifiers(); 
     return !Modifier.isStatic(modifiers); 
    } 

    public boolean fieldDefinedInClass(String fieldName, Class type) { 
     Field field = fieldDictionary.fieldOrNull(type, fieldName, null); 
     return field != null && fieldModifiersSupported(field); 
    } 

} 
+0

這是近3年過去,因爲我不再與怪異的項目工作,且不能不幸的是檢查你的解決方案,但感謝你的輸入是第一人反正回答。 –