使用XStream转换类反序列化两种XML模式未达预期的技术问题
XStream反序列化XML不符合预期的解决方法
问题场景
使用XStream转换类反序列化两种XML结构时,结果未达预期:
模式1
<value>Hello</value>
模式2
<value> <expression> map.message </expression> </value>
对应Java模型
@XStreamAlias("value") @XStreamConverter(value = ToAttributedValueConverter.class, strings = "text") class ValueNode { private String text; private ExpressionNode node; // setter / getter } @XStreamAlias("expression") @XStreamConverter(value = ToAttributedValueConverter.class, strings = "text") class ExpressionNode { private String text; // setter / getter }
实际反序列化结果
| ValueNode.text | ValueNode.node | ExpressionNode.text | |
|---|---|---|---|
| 模式1 | "Hello" | null | - |
| 模式2 | "\n\t\n" | null | - |
预期反序列化结果
| ValueNode.text | ValueNode.node | ExpressionNode.text | |
|---|---|---|---|
| 模式1 | "Hello" | null | - |
| 模式2 | null | 实例 | "map.message" |
解决方法
问题核心是ToAttributedValueConverter的特性:它会将节点的所有文本内容(包括空白字符)强制赋值给strings指定字段,同时默认不处理子节点。需按以下方式调整:
1. 移除ValueNode上的ToAttributedValueConverter注解
该注解会干扰子节点的解析,导致模式2中expression节点无法被识别为node字段,反而把空白文本塞给text。修改后:
@XStreamAlias("value") class ValueNode { private String text; private ExpressionNode node; // setter / getter }
2. 自定义转换器过滤空白文本(可选)
若模式2中value节点的换行、缩进等空白字符导致text被赋值为空字符串,可添加自定义转换器过滤:
public class ValueNodeConverter extends ConverterWrapper { public ValueNodeConverter(Converter wrapped) { super(wrapped); } @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { ValueNode node = (ValueNode) super.unmarshal(reader, context); // 空白文本直接设为null if (node.getText() != null && node.getText().trim().isEmpty()) { node.setText(null); } return node; } @Override public boolean canConvert(Class type) { return ValueNode.class.equals(type); } }
注册转换器:
XStream xstream = new XStream(); xstream.processAnnotations(ValueNode.class); xstream.processAnnotations(ExpressionNode.class); xstream.registerConverter(new ValueNodeConverter(xstream.getConverter(ValueNode.class)));
3. 保留ExpressionNode的转换器
ExpressionNode上的ToAttributedValueConverter可保留,它能自动忽略expression节点内的空白,将有效文本赋值给text字段。
调整后,两种模式的反序列化结果将完全符合预期。
内容的提问来源于stack exchange,提问作者ren130302
相关产品推荐
相关产品推荐

