2012-10-08 2 views
1

Я использую стек Metro в комплекте с Java 6 SE для вызова веб-службы. Веб-служба ожидает XML как параметр. Я использую классы JAXB для создания контента и передачи своего корневого элемента JAXB в конечную точку веб-службы.schemaLocation игнорируется при сортировке JAXB классов с использованием Metro

Теперь к моей проблеме: я не могу найти способ заставить маршаллера включать схему расположения XSD-файла, так как я не могу напрямую обращаться к маршаллеру. (Если у вас есть прямой доступ к маршаллеру, возможно, установите схему как свойство, но при использовании метрополитена все маршаллинг, похоже, происходит внутри.)

Я пробовал установить схему xsi: schemaLocation в Аннотацию XmlSchema в сгенерированном классе package-info.java, но это не повлияло на генерируемый xml.

Еще один момент заключается в том, что при создании клиента веб-службы и вызова веб-службы в среде Java SE некоторые аннотации, такие как @UsesJAXBContext, @WebServiceClient и @XmlSchema, как представляется, игнорируются. (Я должен указать здесь, что я начинаю с точки зрения веб-сервисов Java)

ответ

1

Хорошо, вот что я теперь знаю. Это было проблемой для меня в течение нескольких месяцев.

Во-первых, вам необходимо изменить JAXBContext, используемый JAX-WS. Для этого используйте аннотацию @UsesJAXBContext на сервере. (com.sun.xml.ws.developer.UsesJAXBContext)

Затем в вашей фабричной реализации вы должны вернуть пользовательские мосты в этом методе.

public Bridge createBridge(final TypeReference typereference) 

Тогда ваш пользовательский мост должен установить свойство marshaller для установки планировщика пространства имен, который вы хотите использовать.

Вот мой пример.

@WebService(serviceName = ...) 
@UsesJAXBContext(MyContextFactory.class) 
public class SoapServer { ... } 

и класс завод ...

public static class MyContextFactory implements JAXBContextFactory 
{ 
    @Override 
    public JAXBRIContext createJAXBContext(final SEIModel sei, 
      @SuppressWarnings("rawtypes") final List<Class> classesToBind, final List<TypeReference> typeReferences) 
      throws JAXBException 
    { 
     JAXBRIContext context = JAXBContextFactory.DEFAULT.createJAXBContext(sei, classesToBind, typeReferences); 
     return new MyJaxwsContext(context); 
    } 
} 

и контекст impelementation JAXB ...

public class MyContext extends JAXBRIContext 
{ 
/** the actual context */ 
private final JAXBRIContext delegate; 

public MyContext(final JAXBRIContext createContext) 
{ 
    this.delegate = createContext; 
} 

public Bridge createBridge(final TypeReference arg0) 
{ 
    return new MyBridge((JAXBContextImpl) delegate, delegate.createBridge(arg0)); 
} 

и теперь реализация моста ...

public class MyBridge extends Bridge 
{ 
private final Bridge delegate; 

protected MyBridge(final JAXBContextImpl context, final Bridge delegate) 
{ 
    super(context); 
    this.delegate = delegate; 
} 

// an example marshal call. There are many more... 
public void marshal(final Marshaller m, final Object object, final ContentHandler contentHandler) 
     throws JAXBException 
{ 
    m.setProperty("com.sun.xml.bind.namespacePrefixMapper", namespaceMapper); 
    delegate.marshal(m, object, contentHandler); 
} 

ПРИМЕЧАНИЕ: Я только что завернул существующую реализацию. Все, что я хотел, это уметь фиксировать имена пространства имен. Из моего чтения источника (JAXWS) это единственный способ добраться до маршаллера.

NOTE2 В окончательном классе RI есть опускание. Это работает только с эталонной реализацией. YMMV

+0

Благодарим вас за ответ. Однако ваше предложение, похоже, направлено на разработчиков, которые имеют доступ к серверной стороне, то есть к реализации веб-службы. Это не тот случай. Я только создаю клиента веб-сервиса. Единственной информацией, которую я имею о веб-службе, является wsdl и документация, которая рекомендует помещать схему расположения файла xsd в xml, который передается в конечную точку webservice – Arquebus

+0

Так в чем же проблема? Вы не можете вызвать веб-сервис, потому что получаете какую-то ошибку? Или это более фундаментально? – Zagrev

+0

Это фундаментальная «проблема». Я могу позвонить в webservice, и я не получаю никаких предупреждений или ошибок.Именно так, что поставщик webservice рекомендует установить схему бизнес-xsd, которая описывает схему бизнес-данных, в xml, который должен быть загружен. Мне интересно, почему нет способа сделать это в среде Java SE при использовании стек Metro JAXB, то есть не имеющий доступа к маршаллеру. – Arquebus

Смежные вопросы