Как настроить вывод XML сериализации JAXB на Джерси - PullRequest
4 голосов
/ 12 августа 2011

У меня есть несколько @ javax.xml.bind.annotation.Xml ... аннотированных классов, предназначенных для веб-службы RESt. Джерси настроен в управляемом весной веб-контейнере, и веб-сервис возвращает хорошо отформатированный XML. Мы используем maven-enunciate-plugin для документирования веб-службы и создания xsd для возвращаемых XML-документов. Теперь я хотел бы использовать файл документации xsd в качестве schemaLocation в возвращенном файле XML, чтобы проверка XML не жаловалась на пропущенные определения. Как я могу настроить сериализацию XML для этого?

1 Ответ

7 голосов
/ 18 августа 2011

Если я правильно помню, мне пришлось сделать несколько вещей, чтобы правильно идентифицировать идентификаторы пространства имен в моем сгенерированном XML.

1) Создал JaxbFactory, который конфигурирует и возвращает собственный маршаллер (и unmarshaller, тоже)КСТАТИ)Я опускаю настройки получения и / и демаршаллинга ниже ...

//constructor
public JaxbFactory() throws Exception {
    context = JAXBContext.newInstance(ResourceDto.class);

    // Setup the marshaller
    marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, XmlMetadataConstants.XML_SCHEMA_LOCATION);  // this schema location is used in generating the schema-location property in the xml
}

2) Этот фабричный класс не "виден" Джерси.Чтобы сделать это видимым, я создаю MarshallerProvider.Это выглядит примерно так:

@Provider
public class ResourceJaxbMarshallerProvider implements ContextResolver<Marshaller> {
// injected by Spring
private ResourceJaxbFactory ResourceJaxbFactory;
private ResourceStatusJaxbFactory ResourceStatusJaxbFactory;


/*
 * ----------------------------------------
 * Setters (for Spring injected properties)
 * ----------------------------------------
 */
public void setResourceJaxbFactory(ResourceJaxbFactory ResourceJaxbFactory) {
    this.ResourceJaxbFactory = ResourceJaxbFactory;
}

public void setResourceStatusJaxbFactory(ResourceStatusJaxbFactory ResourceStatusJaxbFactory) {
    this.ResourceStatusJaxbFactory = ResourceStatusJaxbFactory;
}

/*
 * ------------------------
 * Interface Implementation
 * ------------------------
 */
public Marshaller getContext(Class<?> type) {
    if (type == ResourceDto.class)
        return ResourceJaxbFactory.getMarshaller();
    else if (type == ResourceStatusDto.class)
        return ResourceStatusJaxbFactory.getMarshaller();
    else
        return null;
}       
}

Я подключил Джерси к Spring с помощью сервлета Jersey / Spring, поэтому любой класс @Provider, созданный Spring, автоматически распознается Джерси.В моем Spring applicationContext.xml все, что мне нужно сделать, - создать экземпляр поставщика ресурсов.В свою очередь, он возьмет маршаллера с завода.

3) Другая вещь, которую я нашел критической, это то, что мне пришлось создать файл package-info.java в корневом пакете, содержащем мой ресурс.Похоже на это:

/*
 * Note that this file is critical for ensuring that our ResourceDto object is
 * marshalled/unmarshalled with the correct namespace.  Without this, marshalled
 * classes produce XML files without a namespace identifier
 */
@XmlSchema(namespace = XmlMetadataConstants.XML_SCHEMA_NAMESPACE, elementFormDefault = XmlNsForm.QUALIFIED) 
package com.yourcompany.resource;

import javax.xml.bind.annotation.XmlNsForm;

По крайней мере, я думаю , это все, что мне нужно было сделать, я не могу вспомнить каждый кусочек.Я помню, что кусок package-info.java был последним критическим винтиком, который собрал все это вместе.

Надеюсь, это поможет.Я потратил много времени на поиски информации обо всем этом.Джерси был соблазнительно прост, прежде чем я хотел, чтобы он сделал правильную проверку XML-схемы (и приличный отчет об ошибках для ввода неверной схемы).Как только я начал идти по этому пути, Джерси прошел путь от безумно простого до прилично жесткого.Большую часть этой трудности выясняли все детали из множества сообщений в Интернете.Надеюсь, это поможет вам продвинуться дальше, быстрее.: -)

...