【问题标题】:Why does JAX-WS need wrapper classes?为什么 JAX-WS 需要包装类?
【发布时间】:2010-09-14 11:59:27
【问题描述】:

我创建了一个简单的 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 文件中检索到的信息?

【问题讨论】:

标签: java web-services jax-ws


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    如果有入口在服务界面中:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-02
      • 2011-01-09
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2010-11-17
      • 2012-08-13
      • 1970-01-01
      相关资源
      最近更新 更多