2012-01-12 97 views
6

我正在重構一些代碼以使用JAXB和反射向客戶端輸出代碼,它當前使用XMLWriter並且每次都手動創建標記。您可以更改JAXB中的nillable屬性的默認值嗎?

我遇到的問題是由於客戶端的限制,我需要在XML類中爲java類中的任何空字段填充空元素。

雖然我意識到可以通過將nillable=true添加到每個JAXB XmlElement註解來解決這個問題,但這並不是最實際的,因爲我有很多這些註釋。

我希望找到一種方法將nillable=true設置爲全局屬性(或默認值)。這也會使未來的同事更容易開展工作,因爲他們不需要記住每個註釋都應該包含nillable屬性。

除了對默認行爲的描述,我還沒有發現太多內容。我發現過去沒有人發表過類似的問題,這令人驚訝。從我發現的情況來看,在我看來沒有任何內置的支持來實現默認的可配置。這是可以通過定製JAXB實現還是第三方JAXB實現來解決的問題?

回答

1

注:我是EclipseLink JAXB (MOXy)鉛和JAXB 2 (JSR-222)專家小組的成員。

我已經進入了一個增強請求有這種行爲增加的EclipseLink JAXB(莫西):

解決

由於周圍的工作,如果你所有的映射的字符串字段/屬性映射到XML元素,則以下XmlAdapter方法可能適用於您:

NullStringAdapter

XmlAdapter將編組的String實例作爲對象稱爲AdaptedStringAdaptedString包含String值以及映射到xsi:nil屬性的字段。在XmlAdapter中,我們將根據String值是否爲空來設置該字段的值。

package forum8841221; 

import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.*; 

public class NullStringAdapter extends XmlAdapter<NullStringAdapter.AdaptedString, String> { 

    @Override 
    public AdaptedString marshal(String v) throws Exception { 
     AdaptedString adaptedString = new AdaptedString(); 
     if(null == v) { 
      adaptedString.nil = true; 
     } 
     adaptedString.value = v; 
     return adaptedString; 
    } 

    @Override 
    public String unmarshal(AdaptedString v) throws Exception { 
     return v.value; 
    } 

    public static class AdaptedString { 

     @XmlAttribute(namespace="http://www.w3.org/2001/XMLSchema-instance") 
     public Boolean nil; 

     @XmlValue 
     @XmlJavaTypeAdapter(VoidStringAdapter.class) 
     public String value; 

    } 

    public static class VoidStringAdapter extends XmlAdapter<String, String> { 

     @Override 
     public String marshal(String v) throws Exception { 
      return v; 
     } 

     @Override 
     public String unmarshal(String v) throws Exception { 
      return v; 
     } 

    } 

} 

包信息

我們可以註冊,我們希望這個XmlAdapter通過在封裝級註冊XmlAdapter適用於所有的映射String場/關於這個軟件包的屬性。

@XmlJavaTypeAdapter(value=NullStringAdapter.class, type=String.class) 
@XmlSchema(xmlns={@XmlNs(namespaceURI = "http://www.w3.org/2001/XMLSchema-instance", prefix = "xsi")}) 
package forum8841221; 

import javax.xml.bind.annotation.adapters.*; 
import javax.xml.bind.annotation.*; 

下面是我用這個例子的領域類。它有幾個字符串的屬性,它們中的一個註釋有@XmlElement(的nillable =真)

package forum8841221; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Root { 

    private String a; 
    private String b; 
    private String c; 
    private String d; 

    public String getA() { 
     return a; 
    } 

    public void setA(String a) { 
     this.a = a; 
    } 

    public String getB() { 
     return b; 
    } 

    public void setB(String b) { 
     this.b = b; 
    } 

    public String getC() { 
     return c; 
    } 

    public void setC(String c) { 
     this.c = c; 
    } 

    @XmlElement(nillable=true) 
    public String getD() { 
     return d; 
    } 

    public void setD(String d) { 
     this.d = d; 
    } 

} 

演示

package forum8841221; 

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); 

     Root root = new Root(); 
     root.setB("B"); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(root, System.out); 
    } 

} 

輸出

<?xml version="1.0" encoding="UTF-8"?> 
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <a xsi:nil="true"/> 
    <b>B</b> 
    <c xsi:nil="true"/> 
    <d xsi:nil="true"/> 
</root> 
相關問題