XStream转换器,用于将逗号分隔值转换为列表

时间:2014-05-02 11:22:13

标签: xstream

XStream转换器,用于将逗号分隔值转换为列表。

如何为以下代码编写转换器:

<foo> 
 <defaultValues>A,B,C</defaultValues> 
</foo>

我想将逗号分隔值放入一个包含三个元素A,B和B的列表中。下进行。

我已经提到了以下链接,但未获得所需的输出。 XStream converter for XMLList (similar to Jaxb)

由于 比什努

1 个答案:

答案 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);
    }
}