繁体   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