[英]What package-info do I annotate with XmlJavaTypeAdapters?
I've studied Blaise Doughan's answer to a question on this subject but have a further question. 我已经研究过Blaise Doughan对这个问题的答案,但还有一个问题。
XmlJavaTypeAdapters
lets you list a bunch of XmlJavaTypeAdapter
annotations, each of which governs how a non-bindable type is mapped to a bindable type by JAXB. XmlJavaTypeAdapters
允许您列出一堆XmlJavaTypeAdapter
注释,每个注释都控制JAXB如何将不可绑定类型映射到可绑定类型。
You can use this annotation at the package level. 您可以在包级别使用此批注。 When you do so, every XmlJavaTypeAdapter
annotation needs its type()
attribute fully specified. 执行此操作时,每个XmlJavaTypeAdapter
注释都需要完全指定其type()
属性。
There does not appear to be a requirement that the package that is being annotated have anything to do with the package of the non-bindable types being adapted. 似乎没有要求正在注释的包与要调整的不可绑定类型的包有任何关系。 That is convenient and nice. 这很方便,也很好。
That, however, leads me to my next question: if there is no relationship between the annotated package and the package of the type being adapted, how does JAXB discover package-level XmlJavaTypeAdapters
annotations? 然而,这引出了我的下一个问题:如果注释包与被调整类型的包之间没有关系,那么JAXB如何发现包级别的XmlJavaTypeAdapters
注释? How, in other words, does it know which packages to consult for potential XmlJavaTypeAdapters
annotations? 换句话说,它是如何知道哪些包可以参考潜在的XmlJavaTypeAdapters
注释? May I make a random package in, say, a .jar
file in my .ear
file's lib
directory that contains a single, ginormous package-info
class that is annotated with all the adapters for all of my non-bindable types? 我可以在我的.ear
文件的lib
目录中创建一个随机包,比如一个.jar
文件,该文件包含一个单独的ginormous package-info
类,该类使用所有不可绑定类型的所有适配器进行注释?
When the JAXB runtime loads a JAXB-annotated class, it looks for a package-info.java
in the same package as that class, and checks that to look for package-level annotations. 当JAXB运行时加载带有JAXB注释的类时,它会在与该类相同的包中查找package-info.java
,并检查它以查找包级注释。 So while XmlJavaTypeAdapters
doesn't have to reside in the same package as the "non-bindable" types, it does have to reside in the same package as the "bindable" types. 因此,虽然XmlJavaTypeAdapters
不必与“不可绑定”类型驻留在同一个包中,但它必须与“可绑定”类型驻留在同一个包中。
For example, say I have a JAXB-annotated class A
, in package X
, which has a property of type B
in package Y
. 例如,假设我有一个JAXB注释类A
,在包X
,其中有一个类型的属性B
封装Y
。 In order to bind the B
property, let's say a type adapter is required. 为了绑定B
属性,假设需要一个类型适配器。 That adapter can be specified in A
itself, or it can be specified in the package-info.java
in package X
. 该适配器可以在A
本身中指定,也可以在包X
中的package-info.java
中指定。 Package Y
is pretty much arbitrary, and is of no interest to the JAXB runtime. 包Y
非常随意,对JAXB运行时没有兴趣。
I hope that makes sense. 我希望这是有道理的。
There does not appear to be a requirement that the package that is being annotated have anything to do with the package of the non-bindable types being adapted. 似乎没有要求正在注释的包与要调整的不可绑定类型的包有任何关系。 That is convenient and nice. 这很方便,也很好。
This is correct. 这是对的。 When @XmlJavaTypeAdapter
is used at the package level it means apply this adapter to all properties of the specified type for classes that reside in this package. 当在包级别使用@XmlJavaTypeAdapter
时,它意味着将此适配器应用于驻留在此包中的类的指定类型的所有属性。 I'll demonstrate below with an example. 我将在下面举例说明。
forum8735737.bar.package-info forum8735737.bar.package-信息
For this package we will specify an XmlAdapter
that will be applied to all fields/properties of type String
within this package. 对于此包,我们将指定一个XmlAdapter
,该XmlAdapter
将应用于此包中String
类型的所有字段/属性。
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class)
})
package forum8735737.bar;
import javax.xml.bind.annotation.adapters.*;
forum8735737.bar.StringAdapter forum8735737.bar.StringAdapter
Our XmlAdapter
will simply convert all instances of String
to upper case when marshalling: 我们的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 forum8735737.bar.Bar
Bar
represents a POJO in this package with a property of type String
: 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 forum8735737.foo.Foo
Foo represents a domain object with a property of type String
that exists in a different package. Foo表示具有String
类型属性的域对象,该属性存在于不同的包中。 The XmlAdapter
we registered for the forum8735737.bar
package will not apply to this class: 该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;
}
}
Demo 演示
The following code will create instances of both Foo
and Bar
and marshal them to XML: 以下代码将创建Foo
和Bar
实例并将它们封送到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);
}
}
Output 产量
Notice how the value of the name
element within bar
has been converted to upper case: 注意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.