2014-05-02 76 views

回答

0

這裏是用自己的ConverterFoo的解決方案。我希望有一個更簡單的版本,其中CollectionsConverter可以配置。

轉換器:

public final class FooConverter implements Converter { 
    private final Mapper mapper; 

    // XStream can invoke this parametrized constructor 
    public FooConverter(final Mapper mapper) { 
     this.mapper = mapper; 
    } 

    @Override 
    public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { 
     return Foo.class.isAssignableFrom(type); 
    } 

    @Override 
    public void marshal(Object source, HierarchicalStreamWriter writer, 
      MarshallingContext context) { 
     final Foo foo = (Foo) source; 
     // Needed if there is a alias for this member 
     String name = mapper.serializedMember(Foo.class, "defaultValues"); 
     writer.startNode(name); 
     writer.setValue(marshalDefaultValues(foo)); 
     writer.endNode(); 
    } 

    private String marshalDefaultValues(final Foo foo) { 
     final StringBuffer commaSeparatedList = new StringBuffer(); 
     for (Iterator<Character> it = foo.getDefaultValues().iterator(); it 
       .hasNext();) { 
      final char item = it.next(); 
      commaSeparatedList.append(item); 
      if (it.hasNext()) { 
       commaSeparatedList.append(','); 
      } 
     } 

     return commaSeparatedList.toString(); 
    } 

    @Override 
    public Object unmarshal(HierarchicalStreamReader reader, 
      UnmarshallingContext context) { 
     final Foo foo = new Foo(); 

     reader.moveDown(); 
     // Needed if there is a alias for this member 
     String name = mapper.serializedMember(Foo.class, "defaultValues"); 
     if (name.equals(reader.getNodeName())) { 
      final String commaSeparatedList = reader.getValue().trim(); 
      if (!commaSeparatedList.isEmpty()) { 
       final Stream<String> splitted = Arrays 
         .stream(commaSeparatedList.split("\\s*,\\s*")); 
       splitted.map(s -> s.charAt(0)).forEach(c -> { 
        foo.addDefaultValue(c); 
       }); 
      } 
     } else { 
      throw new ConversionException("Expected " + name + ", but was " 
        + name); 
     } 
     reader.moveUp(); 

     return foo; 
    } 
} 

的數據模型:

@XStreamAlias("foo") 
@XStreamConverter(FooConverter.class) 
public final class Foo { 
    private final List<Character> defaultValues = new ArrayList<>(); 

    public void addDefaultValue(char c) { 
     defaultValues.add(c); 
    } 

    public List<Character> getDefaultValues() { 
     return Collections.unmodifiableList(defaultValues); 
    } 
} 

測試序列化和反序列化:

public static void main(String[] args) { 
    final Foo foo1 = new Foo(); 
    foo1.addDefaultValue('A'); 
    foo1.addDefaultValue('B'); 
    foo1.addDefaultValue('C'); 

    final XStream xstream = new XStream(); 
    xstream.autodetectAnnotations(true); 
    final String xml = xstream.toXML(foo1); 
    System.out.println(xml); 

    final Foo foo2 = (Foo) xstream.fromXML(xml); 
    for (final char c : foo2.getDefaultValues()) { 
     System.out.println(c); 
    } 
} 
相關問題