Why does JAX-WS need wrapper classes?

I created a simple web service that implements the add operation, and created some client files using wsimport. Now I want to include as few specific wsdl artifacts as possible. The following is an example of what the web service will be called:

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

But it seems to me that I should include wrapper classes for each post. For example, the message of the result of the add operation:

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

These wrappers are used in annotations in the service interface:

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

If annotations are deleted, the web service will not start.

com.sun.xml.ws.model.RuntimeModelerException: runtime modeling error: shell class org.example.webservices.clients.dynamicproxy.jaxws.Add not found. Did you run APT to create them?

But why do I need these wrappers? Could JAX-WS create these fairings on the fly? Do you see any information that cannot be extracted from the wsdl file?

+4
source share
2 answers

By default, your service is WRAPPED, not BARE, and therefore the top-level element in the message must be a type with the same name as the operation. In the "classic" JAX-WS, this requires you to add a wrapper type.

If you use Apache CXF , it will automatically generate these wrappers using ASM.

+3
source

In the service interface, if you have an entry:

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

Before adding a method in the calculator interface, then you can get wrapper classes created by the JAX-WS client on the fly using the following code:

 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)); } } 
+1
source

All Articles