這裏是用自己的Converter
爲Foo
的解決方案。我希望有一個更簡單的版本,其中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);
}
}