Как получить контроль над JAXBContext в JAX-WS? - PullRequest
6 голосов
/ 05 сентября 2011

Мне нужно развернуть один и тот же веб-сервис для каждого клиента. @javax.jws.WebService использует Object в качестве аргументов метода и возвращаемых типов (в результате <xs:anyType/> в wsdl). Каждый экземпляр веб-службы развертывается вместе с jar клиента на пути к классам. Этот jar имеет известную структуру и содержит JAXB-аннотированные классы, которые клиент хочет обрабатывать через мой сервис.

Проблема в том, что когда клиент передает экземпляр своего класса как метод, контекст JAXB на стороне сервера демаршализирует его в какой-то странный узел xerces dom, потому что (насколько я понимаю) только во время развертывания @WebMethod и @WebService отсканированы аннотации, которые, как уже было сказано, имеют дело только с Object.

Проще говоря, мне нужно указать JAXB на WEB-INF/lib/customer_classes_14586.jar, что означает получение некоторого контроля над созданием JAXBContext во время развертывания JAX-WS.

Возможно ли это вообще?

Подходят для серверных решений (Glassfish 3.1 со стеком metro ws)

UPDATE

Я упустил одну вещь, которая может быть важной: я развертываю эти веб-сервисы как пакеты OSGI во время выполнения через консоль веб-администратора. Когда я нажимаю кнопку развертывания, новый jar программно создается из библиотеки клиента, класса веб-сервиса, wsdl и манифестов. Поэтому я мог бы вмешаться в процесс сборки и предоставить подсказку на данный момент, если это поможет.

Ответы [ 2 ]

4 голосов
/ 06 сентября 2011

Первый вариант - @UsesJAXBContext аннотация.Более подробная информация здесь: Укажите пакеты JAXB в SLSB и JAX-WS

Я не проверял это, потому что, обнаружив эту аннотацию, я уже на полпути к другому решению, которое может быть полезнымдля других.

Ключ использует @WebServiceProvider вместо @WebService, немного низкоуровневый, но простой:

@WebServiceProvider(
  wsdlLocation = "WEB-INF/wsdl/injector.wsdl"
)
@ServiceMode(value = Service.Mode.PAYLOAD)
public class InjectorService implements Provider<Source> {
  private Unmarshaller unmarshaller;

  @Override
  public Source invoke(Source request) {
    try {
      DOMResult requestDom = new DOMResult();
      Transformer trans = TransformerFactory.newInstance().newTransformer();
      trans.transform(request, requestDom);
      Node requestNode = requestDom.getNode();
      // Get the operation name node.
      Node operationNode = requestNode.getFirstChild();
      // Get the parameter node.
      Node parameterNode = operationNode.getFirstChild();
      // Unmarshal
      JAXBElement<Object> element = unmarshaller.unmarshal(parameterNode, Object.class);
      Object unmarshalled = element.getValue();          

      //  Handling customer object and response ......
    } catch (Exception e) {
      throw new RuntimeException("Endpoint error", e);
    }
  }

  protected Class[] getCustomerClasses() {
    // return customer classes somehow
  }

  @PostConstruct
  public void init() throws Exception {
    JAXBContext jbc = JAXBContext.newInstance(getCustomerClasses());
    unmarshaller = jbc.createUnmarshaller();
  }
}

Вот и все.Классы клиентов могут быть получены из classpath, контекста пакета или чего-либо еще.

2 голосов
/ 05 сентября 2011

Из того, что я знаю, не существует "декларативного" способа намека на альтернативный способ отмены маршала, помимо того, который у вас уже есть в соответствии с JAX-WS, или JAXB - то, что вы ищете.Кстати, «странный» узел Xerces действительно ожидается, так как xsd: any / anyType и Object идут рука об руку в вашем сценарии.

Я предлагаю использовать относительно простое и переносимое решение: создайте свойсобственный тонкий «связующий» слой внутри вашего общего веб-метода.Все, что он делает для входящего, - это выполняет демаршаллинг узла XML к классу Java в соответствии с вашими другими привязками JAXB.Затем он должен найти имя пакета Java (для вашего JAXBContext) из QName элемента DOM, не маршалируемого вашим стеком WS.Поиск может использовать файл свойств, отражение или любой другой механизм, специфичный для вашего развертывания.Для исходящего (возврата) вы затем применяете обратную логику, чтобы маршалировать ответ.Этот подход на самом деле довольно распространен, особенно когда другие типы технологий привязки неподдерживаемого XML «туннелируются» через стандартный стек WS.

...