XStream转换器,用于将逗号分隔值转换为列表。
如何为以下代码编写转换器:
<foo>
<defaultValues>A,B,C</defaultValues>
</foo>
我想将逗号分隔值放入一个包含三个元素A,B和B的列表中。下进行。
我已经提到了以下链接,但未获得所需的输出。 XStream converter for XMLList (similar to Jaxb)
由于 比什努
答案 0 :(得分:0)
以下是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);
}
}