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

时间:2012-01-04 23:43:28

标签: java jaxb

我研究过Blaise Doughan's answer to a question on this subject,但还有一个问题。

XmlJavaTypeAdapters允许您列出一堆XmlJavaTypeAdapter注释,每个注释都管理JAXB如何将不可绑定类型映射到可绑定类型。

您可以在包级别使用此批注。执行此操作时,每个XmlJavaTypeAdapter注释都需要完全指定其type()属性。

似乎没有要求正在注释的包与要调整的不可绑定类型的包有任何关系。这很方便也很好。

然而,这引出了我的下一个问题:如果注释包与被调整类型的包之间没有关系,那么JAXB如何发现包级XmlJavaTypeAdapters注释?换句话说,它是如何知道哪些包可以咨询潜在的XmlJavaTypeAdapters注释?我可以在我的.jar文件的.ear目录中的一个lib文件中创建一个随机包,其中包含一个带有所有适配器注释的单个,巨大的package-info类对于我的所有不可绑定类型?

2 个答案:

答案 0 :(得分:8)

当JAXB运行时加载带有JAXB注释的类时,它会在与该类相同的包中查找package-info.java,并检查它以查找包级注释。因此,虽然XmlJavaTypeAdapters不必与“不可绑定”类型驻留在同一个包中,但 必须与“可绑定”类型驻留在同一个包中。 / p>

例如,假设我在包A中有一个带注释JAXB的类X,它在包B中具有类型为Y的属性。为了绑定B属性,假设需要一个类型适配器。该适配器可以在A本身中指定,也可以在包package-info.java中的X中指定。包Y几乎是随意的,对JAXB运行时没有意义。

我希望这是有道理的。

答案 1 :(得分:5)

  

似乎没有要求包装   被注释与包的有关   不可约束的类型被改编。这很方便也很好。

这是对的。在包级别使用@XmlJavaTypeAdapter时,这意味着将此适配器应用于驻留在此包中的类的指定类型的所有属性。我将在下面举例说明。

<强> forum8735737.bar.package-信息

对于此程序包,我们将指定XmlAdapter,该String将应用于此程序包中@XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class) }) package forum8735737.bar; import javax.xml.bind.annotation.adapters.*; 类型的所有字段/属性。

XmlAdapter

<强> forum8735737.bar.StringAdapter

我们的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(); } } 的所有实例转换为大写:

Bar

<强> forum8735737.bar.Bar

String代表此包中的POJO,其属性类型为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; } }

String

<强> forum8735737.foo.Foo

Foo表示具有类型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; } } 将不适用于此类:

Foo

<强>演示

以下代码将创建Barpackage 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); } } 的实例,并将它们编组为XML:

name

<强>输出

注意bar<?xml version="1.0" encoding="UTF-8"?> <foo> <name>Foo</name> </foo> <?xml version="1.0" encoding="UTF-8"?> <bar> <name>BAR</name> </bar> 元素的值是如何转换为大写的:

{{1}}