I am trying to learn about JAX-WS, in particular how to use a complex type. In all three books on Java EE that I have access to, they mention that it is possible, but do not give any example... Strangely, neither search on the web finds one that is complete - including both service and client, but maybe I just cannot locate it.
Here is the service class:
package userobj;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
@WebService(serviceName = "UserObj")
public class UserObj
{
@WebMethod(operationName = "sum")
public int sum(@WebParam(name = "obj") Two obj)
{
return obj.getA() + obj.getB();
}
}
and the class for the corresponding complex type Two:
package userobj;
public class Two
{
private int a, b;
public int getA() { return a; }
public void setA(int newA) { a = newA; }
public int getB() { return b; }
public void setB(int newB) { b = newB; }
}
When I try to use this in a client webservice application, Glassfish4.1 automatically generates all the classes from the WSDL, but the generated class Two looks like this:
package uowsapp;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for two complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="two">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "two")
public class Two {
}
If I manually insert the content of the original class Two to this one, then the application works as expected: UserObjWSApp, but this is probably not intended use case... because Clean&Build on this project regenerates the Two.java and breaks the project. Is there some way I can make sure that Netbeans8.0.2 will generate a proper complex type from the WSDL that it generated itself?
As suggested by maress in his answer, the Two class should follow the requirements of JAXB, however, modifying it like this:
package userobj;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="Two")
public class Two
{
@XmlElement
private int a;
@XmlElement
private int b;
public int getA() { return a; }
public void setA(int newA) { a = newA; }
public int getB() { return b; }
public void setB(int newB) { b = newB; }
}
results in the following exception during the app with service on deploy, and the deploy fails:
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
Class has two properties of the same name "a"
this problem is related to the following location:
at public int userobj.Two.getA()
at userobj.Two
at public userobj.Two userobj.jaxws.Sum.obj
at userobj.jaxws.Sum
this problem is related to the following location:
at private int userobj.Two.a
at userobj.Two
at public userobj.Two userobj.jaxws.Sum.obj
at userobj.jaxws.Sum
and the same for the b property. Then, commenting-out all the getters and setters and making the members public so that they can be accessed directly results in the same behavior as before - the generated class Two has no members. And the same happens when I move the @XmlElement annotation in front of the getA() and getB() methods: deploy ok, WSDL contains a, b, but generated Two does not. Any ideas what else could one try, please?