简体   繁体   English

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

[英]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: 以下代码将创建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);
    }

}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM