我研究过Blaise Doughan's answer to a question on this subject,但还有一个问题。
XmlJavaTypeAdapters
允许您列出一堆XmlJavaTypeAdapter
注释,每个注释都管理JAXB如何将不可绑定类型映射到可绑定类型。
您可以在包级别使用此批注。执行此操作时,每个XmlJavaTypeAdapter
注释都需要完全指定其type()
属性。
似乎没有要求正在注释的包与要调整的不可绑定类型的包有任何关系。这很方便也很好。
然而,这引出了我的下一个问题:如果注释包与被调整类型的包之间没有关系,那么JAXB如何发现包级XmlJavaTypeAdapters
注释?换句话说,它是如何知道哪些包可以咨询潜在的XmlJavaTypeAdapters
注释?我可以在我的.jar
文件的.ear
目录中的一个lib
文件中创建一个随机包,其中包含一个带有所有适配器注释的单个,巨大的package-info
类对于我的所有不可绑定类型?
答案 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
<强>演示强>
以下代码将创建Bar
和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);
}
}
的实例,并将它们编组为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}}