2010-11-10 63 views
4

我有一個遺留類,有很多公共雙字段。所有雙字段都使用Double.MAX_VALUE進行初始化,以表明它們爲空。 (如果字段等於Double.MAX_VALUE,則遺留序列化被編碼爲忽略該字段並且不序列化)。JAXB:如何自定義雙字段的Xml序列化

我們現在試圖使用JAXB Marshaller將此類序列化爲Xml。它工作正常,除了我們想防止爲等於Double.MAX_VALUE的字段生成Xml。

我們沒有使用單獨的JAXB模式,只是用各種javax.xml.bind.annotation註釋標記我們的類。如果使用模式,則可以添加<javaType>元素來指定自定義DataType轉換器。有沒有辦法使用註釋或編程方式來做到這一點?

後想辦法推薦下面,我仍然不能得到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,其中包含TTA的列表。 penstock.data.iserver.OrderResponseWrappers,其延伸com.eztech.OrderResponse。所有雙字段都包含在com.eztech.OrderResponse中。

我的單元測試代碼執行以下操作:

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處理。我知道我錯過了一些基本的東西,但我不確定它是什麼。

回答

9

你可以使用一個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; 
     } 
    } 

} 

模型對象

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的建議是一個很好的一個。如果指定了以下包級別的註釋就可以避免單獨標註所有的雙屬性

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; 
+0

我在看那種方法。問題在於標記遺留類中的所有雙字段是有問題的。我正在尋找一個全局的「鉤子」,我們可以在其中指定或放置上面列出的適配器類型。也就是說,「對於這個類中的每個雙字段,都使用這個XmlAdapter」。 – 2010-11-10 22:07:57

+2

您還可以爲包添加@XmlAdapter註釋(package-info.java可以包含註釋!) - 查看java文檔。這可能會使這種方法可行 – StaxMan 2010-11-11 04:05:18

+0

我已經更新了我的答案,包括了StaxMan的建議。 – 2010-11-11 14:34:35

0

編寫返回null吸氣劑的需求,而不是Double.MAX_VALUE ? (如果type是'double',則需要先將其更改爲'Double',以允許空值)。 由於默認情況下JAXB忽略寫出空值,這應該實現您正在嘗試執行的操作。這假定你可以修改有問題的遺留類。

+1

感謝您的建議。不幸的是,遺留類不能很容易地被修改(並且有「百萬」公共雙字段需要被包裝)。正在尋找更簡單的方法... – 2010-11-10 22:09:05