gpt4 book ai didi

java - 如何使用 XStream 处理相同数据的变体?

转载 作者:行者123 更新时间:2023-12-01 13:27:56 25 4
gpt4 key购买 nike

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

考虑以下类:

用户:

public class User implements Serializable
{

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

...
}

角色:

public class Role implements Serializable
{

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

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

...
}

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

users.xml

<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:

<roles>
<role>
<name>admin<name>
<description>Administrative role</description?
</role>
<role>
<name>deploy<name>
<description>Deployment role</description?
</role>
...
</roles>

但是,我坚持:

<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>

...然而,我希望得到:

<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 中的数据结构不同。所以,我想我需要一个转换器。所以,我敲出了以下内容:

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;
}

}

我的解析器类如下所示:

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 时失败,并出现以下错误:

java.lang.ClassCastException: org.foo.User cannot be cast to org.foo.Role
at org.foo.RoleListConverter.marshal(RoleListConverter.java:35)

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

提前致谢!

最佳答案

可能回答有点晚了......无论如何。

你可以定义

private class UserList extends ArrayList<User> {};
private class RoleList extends ArrayList<Role> {};

xstream.alias("users", UserList.class);
xstream.alias("roles", RoleList.class);

关于java - 如何使用 XStream 处理相同数据的变体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21709707/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com