如何扩展ToAttributedValueConverter以在content为null时跳过序列化
解决方案
你可以通过继承ToAttributedValueConverter重写序列化逻辑实现需求,具体步骤如下:
1. 自定义Converter
import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.mapper.Mapper; import java.lang.reflect.Field; public class SkipNullValueConverter extends ToAttributedValueConverter { private final String valueFieldName; // 构造方法接收value字段名,和原生Converter参数规则一致 public SkipNullValueConverter(Class type, Mapper mapper, String valueFieldName) { super(type, mapper, valueFieldName); this.valueFieldName = valueFieldName; } @Override public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { try { // 读取指定的value字段值 Field field = source.getClass().getDeclaredField(valueFieldName); field.setAccessible(true); Object value = field.get(source); // 值为null直接返回,不输出任何标签内容 if (value == null) { return; } } catch (NoSuchFieldException | IllegalAccessException e) { // 异常场景可根据业务需要调整处理逻辑 e.printStackTrace(); } // 值非空时走原生序列化逻辑 super.marshal(source, writer, context); } }
2. 修改POJO注解
将原来POJO上的@XStreamConverter指定的Converter替换为你自定义的实现即可:
@XStreamAlias("MyPojo") @XStreamConverter(value = SkipNullValueConverter.class, strings = {"content"}) public class MyPojo{ private final String content; private final String attribute1; private final String attribute2; // 注意原代码构造方法名有误,应和类名保持一致为MyPojo public MyPojo(String content, String attribute1, String attribute2) { this.content = content; this.attribute1 = attribute1; this.attribute2 = attribute2; } }
注意事项
- 如果你不想用反射读取字段,可以给POJO添加对应value字段的getter方法,在
marshal方法中直接强转对象调用getter判断,性能更好 - 该自定义Converter是通用实现,其他同类需求的POJO只需在
@XStreamConverter的strings参数中指定对应value字段名即可复用
内容的提问来源于stack exchange,提问作者Walter
相关产品推荐
相关产品推荐

