Returning Complex Type
burakbayramli Nov 19, 2007 4:31 AMHi all,
While trying to return a complex type from a Web Service and I am experiencing some problems:
I am on JBoss 4.2.1.GA and jbossws-1.2.1.GA.
My client receives
Exception in thread "main" org.jboss.ws.WSException: Cannot obtain java/xml type mapping for: {http://service.gg.com/}Product
at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCMetaDataBuilder.processOutputDocElement(JAXRPCMetaDataBuilder.java:778)
at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCMetaDataBuilder.buildParameterMetaDataDoc(JAXRPCMetaDataBuilder.java:897)
at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCMetaDataBuilder.setupOperationsFromWSDL(JAXRPCMetaDataBuilder.java:214)
at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCClientMetaDataBuilder.buildMetaDataInternal(JAXRPCClientMetaDataBuilder.java:216)
at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCClientMetaDataBuilder.buildMetaData(JAXRPCClientMetaDataBuilder.java:133)
at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCClientMetaDataBuilder.buildMetaData(JAXRPCClientMetaDataBuilder.java:85)
at org.jboss.ws.core.jaxrpc.client.ServiceImpl.<init>(ServiceImpl.java:111)
at org.jboss.ws.core.jaxrpc.client.ServiceFactoryImpl.createService(ServiceFactoryImpl.java:157)
at org.jboss.ws.core.jaxrpc.client.ServiceFactoryImpl.createService(ServiceFactoryImpl.java:128)
at com.gg.service.Client.main(Client.java:20)
If I comment out the method which returns the complex type, the client code works fine.
Any ideas would be appreciated,
The code is below;
@WebService
@SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.BARE)
public interface ProductDb extends Remote {
@WebMethod String getProductTitle(int id);
@WebMethod Product getProduct();
}
@Stateless
@WebService(endpointInterface="com.gg.service.ProductDb")
@WebContext(contextRoot="/ggServices")
public class ProductDbBean implements ProductDb {
@PersistenceContext(unitName="GGLocal")
EntityManager em;
public String getProductTitle(int id) {
Product prd = em.find(Product.class, id);
return prd.getTitle();
}
public Product getProduct() {
List<Product> l = em.createQuery("from Product").getResultList();
return l.get(0);
}
}
public class Client
{
public static void main(String[] args) throws Exception
{
URL url = new URL("http://localhost:8080/ggServices/ProductDbBean?wsdl");
QName qname = new QName("http://service.gg.com/", "ProductDbBeanService");
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(url, qname);
ProductDb s = (ProductDb) service.getPort(ProductDb.class);
String test = s.getProductTitle(1);
}
}
WSDL
<definitions name='ProductDbBeanService' targetNamespace='http://service.gg.com/' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://service.gg.com/' xmlns:xsd='http://www.w3.org/2001/XMLSchema'> <types> <xs:schema targetNamespace='http://service.gg.com/' version='1.0' xmlns:tns='http://service.gg.com/' xmlns:xs='http://www.w3.org/2001/XMLSchema'> <xs:element name='Product' type='tns:Product'/> <xs:element name='getProductResponse' nillable='true' type='tns:Product'/> <xs:element name='getProductTitle' type='xs:int'/> <xs:element name='getProductTitleResponse' nillable='true' type='xs:string'/> <xs:complexType name='Product'> <xs:sequence> <xs:element form='qualified' name='id' type='xs:int'/> <xs:element form='qualified' name='title' type='xs:string'/> </xs:sequence> </xs:complexType> </xs:schema> </types> <message name='ProductDb_getProduct'></message> <message name='ProductDb_getProductResponse'> <part element='tns:getProductResponse' name='getProductResponse'></part> </message> <message name='ProductDb_getProductTitleResponse'> <part element='tns:getProductTitleResponse' name='getProductTitleResponse'></part> </message> <message name='ProductDb_getProductTitle'> <part element='tns:getProductTitle' name='getProductTitle'></part> </message> <portType name='ProductDb'> <operation name='getProduct'> <input message='tns:ProductDb_getProduct'></input> <output message='tns:ProductDb_getProductResponse'></output> </operation> <operation name='getProductTitle' parameterOrder='getProductTitle'> <input message='tns:ProductDb_getProductTitle'></input> <output message='tns:ProductDb_getProductTitleResponse'></output> </operation> </portType> <binding name='ProductDbBinding' type='tns:ProductDb'> <soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='getProduct'> <soap:operation soapAction=''/> <input> <soap:body use='literal'/> </input> <output> <soap:body use='literal'/> </output> </operation> <operation name='getProductTitle'> <soap:operation soapAction=''/> <input> <soap:body use='literal'/> </input> <output> <soap:body use='literal'/> </output> </operation> </binding> <service name='ProductDbBeanService'> <port binding='tns:ProductDbBinding' name='ProductDbBeanPort'> <soap:address location='http://127.0.0.1:8080/ggServices/ProductDbBean'/> </port> </service> </definitions>
POJO:
@Entity
@Table(name="urun")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Product", namespace="http://service.gg.com/",
propOrder = { "id", "title"})
@XmlRootElement(namespace="http://service.gg.com/", name = "Product")
public class Product implements Serializable {
@Id
@Column(name="urun_id")
@XmlElement(namespace="http://service.gg.com/", required = true)
private Integer id;
@Column(length=60)
@XmlElement(namespace="http://service.gg.com/", required = true)
private String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}