为什么JAX-WS需要包装类?

时间:2010-09-14 11:59:27

标签: java web-services jax-ws

我创建了一个简单的Web服务,它实现了一个添加操作,并使用wsimport创建了一些客户端文件。现在我想尽可能少地包含wsdl特定的工件。以下是如何调用Web服务的示例:

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);
}

如果删除了注释,则Web服务将无法运行。

  

com.sun.xml.ws.model.RuntimeModelerException:运行时建模器错误:找不到包装器类org.example.webservices.clients.dynamicproxy.jaxws.Add。你有没有运行APT来生成它们?

但为什么我需要这些包装? JAX-WS无法即时创建这些包装器吗?您是否看到了无法从wsdl文件中检索到的任何信息?

2 个答案:

答案 0 :(得分:3)

默认情况下,您的服务是WRAPPED,而不是BARE,因此消息中的顶级项必须是与操作同名的类型。在'经典'JAX-WS中,这需要您添加包装类型。

如果您使用Apache CXF,它将使用ASM自动生成这些包装器。

答案 1 :(得分:1)

如果您有条目,请在服务界面中:

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

在Calculator接口中的 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));     
  }
}