JAXB:如何自定义双字段的Xml序列化

我有一个遗留类,有很多公共双字段。 使用Double.MAX_VALUE初始化所有双字段以指示它们为空。 (遗留序列化被编码为忽略该字段,如果字段等于Double.MAX_VALUE则不进行序列化)。

我们现在尝试使用JAXB Marshaller将此类序列化为Xml。 它工作正常,除了我们想要阻止为等于Double.MAX_VALUE字段生成Xml。

我们没有使用单独的JAXB模式,只是用各种javax.xml.bind.annotation注释来标记我们的类。 如果使用模式,则可以添加元素以指定自定义DataType转换器。 有没有办法使用Annotations或以编程方式执行此操作?

在尝试下面推荐的方法之后,我仍然无法获得XmlAdapter

 @XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(value=EmptyDoubleValueHandler.class, type=Double.class), @XmlJavaTypeAdapter(value=EmptyDoubleValueHandler.class, type=double.class)}) package tta.penstock.data.iserver; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; 

我的顶级课程是:tta.penstock.data.iserver.OrderBlotter,其中包含扩展com.eztech.OrderResponse的tta.penstock.data.iserver.OrderResponseWrappers列表。 所有双字段都包含在com.eztech.OrderResponse

我的unit testing代码执行以下操作:

 JAXBContext context = JAXBContext.newInstance(new Class[] { OrderBlotter.class, OrderResponseWrapper.class, OrderResponse.class}); Marshaller marshaller = context.createMarshaller(); StringWriter stringWriter = new StringWriter(); marshaller.marshal(blotter, stringWriter); System.out.println("result xml=\n" + stringWriter.toString()); 

但是双值仍然无法由XmlAdapter处理。 我知道我遗漏了一些基本的东西,但我不确定它是什么。

您可以使用XmlAdapter:

XmlAdapter

 package example; import javax.xml.bind.annotation.adapters.XmlAdapter; public class DoubleAdapter extends XmlAdapter{ @Override public Double unmarshal(Double v) throws Exception { return v; } @Override public Double marshal(Double v) throws Exception { if(Double.MAX_VALUE == v) { return null; } else { return v; } } } 

模型对象

 package example; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlRootElement public class Root { @XmlJavaTypeAdapter(DoubleAdapter.class) public Double maxDouble = Double.MAX_VALUE; @XmlJavaTypeAdapter(DoubleAdapter.class) public Double aDouble = 123d; } 

演示代码

 package example; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(new Root(), System.out); } } 

UPDATE

StaxMan的建议很好。 如果指定以下包级别注释,则可以避免单独注释所有Double属性

package-info.java

 @XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(type=Double.class, value=DoubleAdapter.class) }) package example; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; 

写一个返回null的getter,而不是Double.MAX_VALUE? (如果type为’double’,则需要先将其更改为’Double’,以允许空值)。 由于JAXB默认忽略写出空值,因此应该实现您要做的事情。 这假设您可以修改有问题的遗留类。