Какую информацию о пакете я аннотирую с помощью XmlJavaTypeAdapters? - PullRequest
8 голосов
/ 05 января 2012

Я изучил Ответ Блейза Дафана на вопрос по этому вопросу , но у меня есть еще вопрос.

XmlJavaTypeAdapters позволяет составить список аннотаций XmlJavaTypeAdapter, каждая из которых определяет, как несвязываемый тип отображается в связываемый тип с помощью JAXB.

Вы можете использовать эту аннотацию на уровне пакета. При этом для каждой аннотации XmlJavaTypeAdapter должен быть полностью указан атрибут type().

По-видимому, не существует требования, чтобы аннотируемый пакет имел какое-либо отношение к пакету адаптируемых несвязываемых типов. Это удобно и приятно.

Это, однако, приводит меня к моему следующему вопросу: если нет никакой связи между аннотированным пакетом и пакетом адаптируемого типа, как JAXB обнаруживает аннотации XmlJavaTypeAdapters уровня пакета? Как, другими словами, он узнает, с какими пакетами обращаться к потенциальным аннотациям XmlJavaTypeAdapters? Могу ли я создать случайный пакет, скажем, в файле .jar в каталоге lib моего .ear файла, который содержит один класс ginormous package-info, который аннотирован всеми адаптерами для всех моих типов, не связанных

Ответы [ 2 ]

8 голосов
/ 05 января 2012

Когда среда выполнения JAXB загружает JAXB-аннотированный класс, он ищет package-info.java в том же пакете, что и этот класс, и проверяет его на наличие аннотаций на уровне пакета.Таким образом, хотя XmlJavaTypeAdapters не обязательно должен находиться в том же пакете, что и типы «без привязки», он должен находиться в том же пакете, что и «связываемые» типы.

Например, скажем, у меня есть JAXB-аннотированный класс A в пакете X, который имеет свойство типа B в пакете Y.Чтобы связать свойство B, скажем, требуется адаптер типа.Этот адаптер может быть указан в самом A или в package-info.java в пакете X.Пакет Y в значительной степени произвольный и не представляет интереса для среды выполнения JAXB.

Надеюсь, это имеет смысл.

5 голосов
/ 05 января 2012

По-видимому, не существует требования, чтобы аннотируемый пакет имел какое-либо отношение к пакету адаптируемых несвязываемых типов.Это удобно и приятно.

Это правильно.Когда @XmlJavaTypeAdapter используется на уровне пакета, это означает, что этот адаптер применяется ко всем свойствам указанного типа для классов, которые находятся в этом пакете.Ниже я продемонстрирую пример:

forum8735737.bar.package-info

Для этого пакета мы определим 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;
    }

}

Демо

Следующий код создаст экземпляры обоих 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);
    }

}

Вывод

Обратите внимание, как значение элемента 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...