在我的场景中,我使用的是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中的数据结构不同。所以,我想我需要一个Converter。所以,我做了以下几件事:
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)显然,当我注册这个转换器的时候,它会试图拦截所有的列表并搞砸。我在这里做错了什么,怎么才能实现我的目标?
提前感谢!
发布于 2014-02-26 00:15:14
可能有点晚了.不管怎么说。
你可以定义
private class UserList extends ArrayList<User> {};
private class RoleList extends ArrayList<Role> {};
xstream.alias("users", UserList.class);
xstream.alias("roles", RoleList.class);https://stackoverflow.com/questions/21709707
复制相似问题