Зачем JAX-WS нужны классы-оболочки? - PullRequest
4 голосов
/ 14 сентября 2010

Я создал простой веб-сервис, который реализует операцию добавления, и создал несколько клиентских файлов с помощью wsimport. Теперь я хочу включить как можно меньше конкретных артефактов wsdl. Вот пример того, как будет называться веб-сервис:

String serviceNamespace = "http://jws.samples.geronimo.apache.org/";
String serviceName = "CalculatorServiceService";
QName serviceQN = new QName(serviceNamespace, serviceName);
Service service = Service.create(new URL("http://localhost:8080/WebService/calculator?wsdl"), serviceQN);

String portNamespace = "http://jws.samples.geronimo.apache.org/";
String portName = "CalculatorServicePort";
QName portQN = new QName(portNamespace, portName);
Calculator myProxy = (Calculator) service.getPort(portQN, Calculator.class);

Но, похоже, мне нужно включать классы-оболочки для каждого сообщения. Например, сообщение о результате операции добавления:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "addResponse", propOrder = { "_return" })
public class AddResponse {
    @XmlElement(name = "return")
    protected int _return;
    public int getReturn() {
        return _return;
    }
    public void setReturn(int value) {
        this._return = value;
    }
}

Эти оболочки используются в аннотациях в интерфейсе сервиса:

@WebService(name = "Calculator", targetNamespace = "http://jws.samples.geronimo.apache.org/")
public interface Calculator {
    @WebMethod
    @RequestWrapper(className = "org.example.webservices.clients.dynamicproxy.Add")
    @ResponseWrapper(className = "org.example.webservices.clients.dynamicproxy.AddResponse")
    public int add(
        @WebParam(name = "value1", targetNamespace = "")
        int value1,
        @WebParam(name = "value2", targetNamespace = "")
        int value2);
}

Если аннотации будут удалены, веб-служба не запустится.

com.sun.xml.ws.model.RuntimeModelerException: ошибка средства моделирования во время выполнения: класс-оболочка org.example.webservices.clients.dynamicproxy.jaxws.Add не найден. Вы запускали APT для их генерации?

Но зачем мне эти обертки? Разве JAX-WS не может создавать эти оболочки на лету? Видите ли вы какую-либо информацию, которую невозможно получить из файла wsdl?

Ответы [ 2 ]

3 голосов
/ 18 декабря 2010

По умолчанию ваш сервис WRAPPED, а не BARE, поэтому элемент верхнего уровня в сообщении должен иметь тип с тем же именем, что и у операции. В «классическом» JAX-WS для этого требуется добавить тип оболочки.

Если вы используете Apache CXF , он автоматически сгенерирует эти оболочки с ASM.

1 голос
/ 06 марта 2013

В интерфейсе службы, если у вас есть запись:

@WebResult(targetNamespace = "http://jws.samples.geronimo.apache.org/")

до add метода в интерфейсе калькулятора, вы можете получить классы-оболочки, созданные JAX-WS.клиент на лету, используя следующий код:

import java.net.URL;

import javax.xml.namespace.QName;

import javax.xml.ws.Service;

public class TestWS{

  public static void main(String args[]) throws Exception
  {
     URL url = "url to wsdl"

     QName qname = new QName("http://jws.samples.geronimo.apache.org/", "Name of your service" );
     Service service = Service.create(url, qname);
     Calculator calcPort = service.getPort(Calculator.class);
     System.out.println("Result of 1+2 is " + calcPort.add(1,2));     
  }
}
...