java JAXB:如何自定义双字段的 Xml 序列化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4148192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JAXB: How to customize Xml serialization of double fields
提问by Sam Goldberg
I have a legacy class, with a lot of public double fields. All double fields are initialized with Double.MAX_VALUE
to indicate that they are empty. (The legacy serialization is coded to ignore the field and not serialize if field is equals to Double.MAX_VALUE
).
我有一个遗留类,有很多公共双字段。所有双字段都初始化为Double.MAX_VALUE
以指示它们为空。(旧序列化被编码为忽略该字段,如果字段等于 则不序列化Double.MAX_VALUE
)。
We are now trying to serialize this class to Xml using JAXB Marshaller. It is working fine, except that we want to prevent generating Xml for fields which equal Double.MAX_VALUE
.
我们现在正在尝试使用 JAXB Marshaller 将此类序列化为 Xml。它工作正常,除了我们想要防止为等于Double.MAX_VALUE
.
We aren't using a separate JAXB schema, just marking up our classes with various javax.xml.bind.annotation
Annotations. If a schema is used, you can add a <javaType>
element to specify a custom DataType converter. Is there any way to do this using Annotations or programmatically?
我们没有使用单独的 JAXB 模式,只是用各种javax.xml.bind.annotation
注释标记我们的类。如果使用架构,您可以添加一个<javaType>
元素来指定自定义数据类型转换器。有没有办法使用注释或以编程方式做到这一点?
After trying approach recommended below, I still can't get XmlAdapter
picked up:
在尝试了下面推荐的方法后,我仍然无法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;
My top level class is: tta.penstock.data.iserver.OrderBlotter, which contains a list of tta.penstock.data.iserver.OrderResponseWrappers which extends com.eztech.OrderResponse
. All the double fields are contained in com.eztech.OrderResponse
.
我的顶级类是:tta.penstock.data.iserver.OrderBlotter,它包含一个 tta.penstock.data.iserver.OrderResponseWrappers 的列表,它扩展了com.eztech.OrderResponse
. 所有双字段都包含在com.eztech.OrderResponse
.
My unit test code does the following:
我的单元测试代码执行以下操作:
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());
But the double values still don't get handled by the XmlAdapter
. I know I'm missing something basic, but I'm not sure what it is.
但是双值仍然没有被XmlAdapter
. 我知道我缺少一些基本的东西,但我不确定它是什么。
回答by bdoughan
You could use an XmlAdapter:
您可以使用 XmlAdapter:
The XmlAdapter
XmlAdapter
package example;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class DoubleAdapter extends XmlAdapter<Double, Double>{
@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;
}
}
}
The Model Object
模型对象
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;
}
Demo Code
演示代码
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's suggestion is a good one. If you specify the following package level annotation you can avoid the need of individually annotating all the Double properties
StaxMan 的建议很好。如果指定以下包级别注释,则可以避免单独注释所有 Double 属性的需要
package-info.java
包信息.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;
回答by StaxMan
Write a getter that returns null, instead of Double.MAX_VALUE? (if type is 'double', need to change it to 'Double' first, to allow nulls). Since JAXB by default ignores writing out of nulls, that should achieve what you are trying to do. This assumes you can modify legacy class in question.
编写一个返回 null 而不是 Double.MAX_VALUE 的 getter?(如果类型是'double',需要先将其更改为'Double',以允许空值)。由于默认情况下 JAXB 忽略写出空值,这应该可以实现您想要做的事情。这假设您可以修改有问题的遗留类。