Системный адаптер в Джерси? - PullRequest
3 голосов
/ 10 июля 2010

Я пытаюсь настроить "системную" пользовательскую javax.xml.bind.annotation.adapters.XmlAdapter для типа java.util.Locale в Джерси.Достаточно просто использовать @XmlJavaTypeAdapter на классах, которыми я управляю, но это не всегда так (сторонний код, который я не могу комментировать).

Кажется, что это будет довольно распространенная проблема, но я могу 'Не могу найти хороших примеров или документов о том, как с этим справиться.

Итак, возможно ли это?

Спасибо!

Ответы [ 3 ]

1 голос
/ 12 июля 2010

Если вам нужно аннотировать классы, которые вы не можете изменить, вы всегда можете использовать функцию внешних метаданных из EclipseLink JAXB (MOXy) .

Метаданныефайл будет выглядеть примерно так:

<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm">
    <java-types>
        <java-type name="java.util.Locale">
            <xml-java-type-adapter value="some.package.YourAdapter"/>
        </java-type>
    </java-types>
</xml-bindings>

Для вас, EclipseLink MOXy, вам нужно добавить файл jaxb.properties в классы вашей модели со следующей записью:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
1 голос
/ 10 июля 2010

Я вижу три возможных варианта:

  1. Зарегистрируйте преобразователь с помощью маршаллера с помощью setAdapter () . Вы можете иметь функцию статического компоновщика, которая добавляет все ваши адаптеры типа «системный уровень» ко всем маршаллерам, которые вы используете в своем приложении. Все зависит от вашего определения «системный уровень»
  2. Использовать делегата
  3. Придумайте хитрость байт-кода , чтобы добавить аннотации к существующим файлам классов.

Мой совет будет использовать подход 1, который прост и понятен.

0 голосов
/ 13 июня 2011

Вы также можете посмотреть проект JAXBIntroductions , который предназначен для аналогичной цели. Конфигурация аннотации хранится в файле, не требуя изменения исходного кода. Он хорошо работает с Джерси, внедряя провайдера JAX-RS. Вы можете проверить мой блог запись , которая подробно объясняет это на примере. Вот простой JAXBContextResolver, предоставляющий JAXBIntroductions, который можно использовать в вашем приложении на Джерси.

import com.sun.xml.bind.api.JAXBRIContext;
import org.jboss.jaxb.intros.IntroductionsAnnotationReader;
import org.jboss.jaxb.intros.IntroductionsConfigParser;
import org.jboss.jaxb.intros.configmodel.JaxbIntros;

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import java.util.*;

@Provider
public class JAXBContextResolverForJAXBIntroductions implements ContextResolver<JAXBContext> {

    private final JAXBContext context;
    private final Set<Class> types;
    private final Class[] cTypes = {Customer.class};

    public JAXBContextResolverForJAXBIntroductions() throws Exception {
        this.types = new HashSet(Arrays.asList(cTypes));
        JaxbIntros config = IntroductionsConfigParser.parseConfig(this.getClass().getResourceAsStream("/intro-config.xml"));
        IntroductionsAnnotationReader reader = new IntroductionsAnnotationReader(config);
        Map<String, Object> jaxbConfig = new HashMap<String, Object>();
        jaxbConfig.put(JAXBRIContext.ANNOTATION_READER, reader);
        this.context = JAXBContext.newInstance(cTypes, jaxbConfig);
    }

    public JAXBContext getContext(Class<?> objectType) {
        return (types.contains(objectType)) ? context : null;
    }
}
...