首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将XStream与相同数据的变体一起使用?

如何将XStream与相同数据的变体一起使用?
EN

Stack Overflow用户
提问于 2014-02-11 18:09:04
回答 1查看 110关注 0票数 0

在我的场景中,我使用的是XStream,我需要能够在不同的变体中存储/解析相同的数据。

考虑以下几类:

用户:

代码语言:javascript
运行
复制
public class User implements Serializable
{

    @XStreamAlias(value = "roles")
    private List<Role> roles = new ArrayList<Role>();

    ...
}

角色:

代码语言:javascript
运行
复制
public class Role implements Serializable
{

    @XStreamAlias(value = "name")
    private String name;

    @XStreamAlias(value = "description")
    private String description;

    ...
}

我需要能够产生以下产出:

users.xml

代码语言:javascript
运行
复制
<users>
    <user>
        <username>admin</username>
        <password>password</password>
        <roles>
            <role>administrator</role>
        </roles>
    </user>
    <user>
        <username>deployer</username>
        <password>password</password>
        <roles>
            <role>deploy</role>
        </roles>
    </user>
</users>

roles.xml:

代码语言:javascript
运行
复制
<roles>
    <role>
        <name>admin<name>
        <description>Administrative role</description?
    </role>
    <role>
        <name>deploy<name>
        <description>Deployment role</description?
    </role>
    ...
</roles>

然而,我仍然坚持着:

代码语言:javascript
运行
复制
<users>
    <user>
        <username>admin</username>
        <password>password</password>
        <roles>
            <role>
                <name>admin</name>
            </role>
        </roles>
    </user>
    <user>
        <username>deployer</username>
        <password>password</password>
        <roles>
            <role>
                <name>deploy</name>
            </role>
            <role>
                <name>read</name>
            </role>
            <role>
                <name>delete</name>
            </role>
        </roles>
    </user>
</users>

..。然而,我想要得到:

代码语言:javascript
运行
复制
<users>
    ...
    <user>
        <username>deployer</username>
        <password>password</password>
        <roles>
            <role>
                <name>deploy</name>
                <name>read</name>
                <name>delete</name>
            </role>
        </roles>
    </user>
    ...
</users>

这可以理解。User DTO中的数据结构不同。所以,我想我需要一个Converter。所以,我做了以下几件事:

代码语言:javascript
运行
复制
public class RoleListConverter
        implements Converter
{

    public boolean canConvert(Class clazz)
    {
        return AbstractList.class.isAssignableFrom(clazz);
    }

    public void marshal(Object value,
                        HierarchicalStreamWriter writer,
                        MarshallingContext context)
    {
        if (value instanceof List)
        {
            //noinspection unchecked
            List<Role> roles = (List<Role>) value;

            for (Role role : roles)
            {
                writer.startNode("role");
                writer.setValue(role.getName());
                writer.endNode();
            }
        }
    }

    public Object unmarshal(HierarchicalStreamReader reader,
                            UnmarshallingContext context)
    {
        List<Role> roles = new ArrayList<Role>();

        while (reader.hasMoreChildren())
        {
            reader.moveDown();

            Role role = new Role();

            final String nodeName = reader.getNodeName();
            if (nodeName.equals("role"))
            {
                role.setName(reader.getValue().trim());
                roles.add(role);
            }

            reader.moveUp();
        }

        return roles;
    }

}

我的解析器类如下所示:

代码语言:javascript
运行
复制
public class UserParser
        extends GenericParser<User>
{
    ...
    public XStream getXStreamInstance()
    {
        XStream xstream = new XStream();
        xstream.autodetectAnnotations(true);
        xstream.alias("user", User.class);
        xstream.alias("users", List.class);
        xstream.alias("role", Role.class);
        xstream.alias("credentials", Credentials.class);
        xstream.registerConverter(new RoleListConverter());

        return xstream;
    }
    ...
}

当试图使用以下错误存储XML时,此操作将失败:

代码语言:javascript
运行
复制
java.lang.ClassCastException: org.foo.User cannot be cast to org.foo.Role
    at org.foo.RoleListConverter.marshal(RoleListConverter.java:35)

显然,当我注册这个转换器的时候,它会试图拦截所有的列表并搞砸。我在这里做错了什么,怎么才能实现我的目标?

提前感谢!

EN

回答 1

Stack Overflow用户

发布于 2014-02-26 00:15:14

可能有点晚了.不管怎么说。

你可以定义

代码语言:javascript
运行
复制
private class UserList extends ArrayList<User> {};
private class RoleList extends ArrayList<Role> {};

xstream.alias("users", UserList.class); 
xstream.alias("roles", RoleList.class);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21709707

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档