簡體   English   中英

我用XmlJavaTypeAdapters注釋了什么package-info?

[英]What package-info do I annotate with XmlJavaTypeAdapters?

我已經研究過Blaise Doughan對這個問題的答案,但還有一個問題。

XmlJavaTypeAdapters允許您列出一堆XmlJavaTypeAdapter注釋,每個注釋都控制JAXB如何將不可綁定類型映射到可綁定類型。

您可以在包級別使用此批注。 執行此操作時,每個XmlJavaTypeAdapter注釋都需要完全指定其type()屬性。

似乎沒有要求正在注釋的包與要調整的不可綁定類型的包有任何關系。 這很方便,也很好。

然而,這引出了我的下一個問題:如果注釋包與被調整類型的包之間沒有關系,那么JAXB如何發現包級別的XmlJavaTypeAdapters注釋? 換句話說,它是如何知道哪些包可以參考潛在的XmlJavaTypeAdapters注釋? 我可以在我的.ear文件的lib目錄中創建一個隨機包,比如一個.jar文件,該文件包含一個單獨的ginormous package-info類,該類使用所有不可綁定類型的所有適配器進行注釋?

當JAXB運行時加載帶有JAXB注釋的類時,它會在與該類相同的包中查找package-info.java ,並檢查它以查找包級注釋。 因此,雖然XmlJavaTypeAdapters不必與“不可綁定”類型駐留在同一個包中,但必須與“可綁定”類型駐留在同一個包中。

例如,假設我有一個JAXB注釋類A ,在包X ,其中有一個類型的屬性B封裝Y 為了綁定B屬性,假設需要一個類型適配器。 該適配器可以在A本身中指定,也可以在包X中的package-info.java中指定。 Y非常隨意,對JAXB運行時沒有興趣。

我希望這是有道理的。

似乎沒有要求正在注釋的包與要調整的不可綁定類型的包有任何關系。 這很方便,也很好。

這是對的。 當在包級別使用@XmlJavaTypeAdapter時,它意味着將此適配器應用於駐留在此包中的類的指定類型的所有屬性。 我將在下面舉例說明。

forum8735737.bar.package-信息

對於此包,我們將指定一個XmlAdapter ,該XmlAdapter將應用於此包中String類型的所有字段/屬性。

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class)
})
package forum8735737.bar;

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

forum8735737.bar.StringAdapter

我們的XmlAdapter將在編組時簡單地將所有String實例轉換為大寫:

package forum8735737.bar;

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

public class StringAdapter extends XmlAdapter<String, String> {

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

    @Override
    public String marshal(String v) throws Exception {
        if(null == v) {
            return v;
        }
        return v.toUpperCase();
    }

}

forum8735737.bar.Bar

Bar表示此包中的POJO,其屬性類型為String

package forum8735737.bar;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Bar {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

forum8735737.foo.Foo

Foo表示具有String類型屬性的域對象,該屬性存在於不同的包中。 XmlAdapter我們注冊了forum8735737.bar包將不會適用於這個類:

package forum8735737.foo;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Foo {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

演示

以下代碼將創建FooBar實例並將它們封送到XML:

package forum8735737;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import forum8735737.bar.Bar;
import forum8735737.foo.Foo;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class, Bar.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        Foo foo = new Foo();
        foo.setName("Foo");
        marshaller.marshal(foo, System.out);

        Bar bar = new Bar();
        bar.setName("Bar");
        marshaller.marshal(bar, System.out);
    }

}

產量

注意bar name元素的值是如何轉換為大寫的:

<?xml version="1.0" encoding="UTF-8"?>
<foo>
   <name>Foo</name>
</foo>
<?xml version="1.0" encoding="UTF-8"?>
<bar>
   <name>BAR</name>
</bar>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM