0
在我的場景中,我使用XStream,我需要能夠以不同的變體存儲/解析相同的數據。如何將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)
顯然,當我註冊這個轉換器時,它會嘗試攔截所有列表並將其鎖定。我在這裏做錯了什麼,以及如何實現我的目標?
在此先感謝!
有趣的方法,謝謝! – carlspring