Jaxws doesn't populate results - java

I have a working web service made with Axis1, and I'm migrating it to Jaxws
I'm creating my client classes with wsimport and maven from my working WSDL file.
The problem I have is that I can see my SOAP response message with data in my logger, but the objects aren't populated with this data.
My wsdl looks like this (I posted only 1 service to make it shorter and removed some of the elements, so please ignore if there are some missing like ResultadoProcesamiento):
<wsdl:definitions targetNamespace="http://ws.test" xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://ws.test"
xmlns:intf="http://ws.test"
xmlns:tns1="http://pojo.test"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="http://ws.test" xmlns="http://www.w3.org/2001/XMLSchema" >
<import namespace="http://pojo.test"/>
<element name="validarCertificado">
<complexType>
<sequence>
<element name="cert" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="validarCertificadoResponse">
<complexType>
<sequence>
<element name="validarCertificadoReturn" type="tns1:MensajeSalida"/>
</sequence>
</complexType>
</element>
</schema>
<schema elementFormDefault="qualified" targetNamespace="http://pojo.test" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://ws.test"/>
<complexType name="Respuesta">
<sequence>
<element name="excepcion" nillable="true" type="tns1:Excepcion"/>
<element name="resultadoProcesamiento" nillable="true" type="tns1:ResultadoProcesamiento"/>
</sequence>
</complexType>
<complexType name="MensajeSalida">
<sequence>
<element name="peticion" nillable="true" type="xsd:string"/>
<element name="respuesta" nillable="true" type="tns1:Respuesta"/>
<element name="versionMsg" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="validarCertificadoRequest">
<wsdl:part element="impl:validarCertificado" name="parameters"/>
</wsdl:message>
<wsdl:message name="validarCertificadoResponse">
<wsdl:part element="impl:validarCertificadoResponse" name="parameters"/>
</wsdl:message>
<wsdl:portType name="WsTest">
<wsdl:operation name="validarCertificado">
<wsdl:input message="impl:validarCertificadoRequest" name="validarCertificadoRequest"/>
<wsdl:output message="impl:validarCertificadoResponse" name="validarCertificadoResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WsTestSoapBinding" type="impl:WsTest">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="validarCertificado">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="validarCertificadoRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="validarCertificadoResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="WsTestService">
</wsdl:service>
</wsdl:definitions>
I forced to create 2 packages because I had some elements with the same name but from different schemas.
First package:
package-info.java
#XmlSchema(namespace = "http://ws.test", elementFormDefault = XmlNsForm.QUALIFIED)
package test.ws;
ValidarCertificadoResponse.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = { "validarCertificadoReturn" })
#XmlRootElement(name = "validarCertificadoResponse")
public class ValidarCertificadoResponse {
#XmlElement(required = true)
protected MensajeSalida validarCertificadoReturn;
Second package:
package-info.java
#XmlSchema(namespace = "http://pojo.test", elementFormDefault = XmlNsForm.QUALIFIED)
package pojo.ws;
MensajeSalida.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "MensajeSalida", propOrder = { "peticion", "respuesta", "versionMsg" })
public class MensajeSalida {
#XmlElement(required = true, nillable = true)
protected String peticion;
#XmlElement(required = true, nillable = true)
protected Respuesta respuesta;
#XmlElement(required = true, nillable = true)
protected String versionMsg;
And my response SOAP message (it includes only some tags):
<soapenv:Body>
<validarCertificadoResponse xmlns="http://ws.test">
<validarCertificadoReturn>
<peticion>value1</peticion>
<respuesta>
datas
<respuesta/>
<resultadoProcesamiento>
more datas
</resultadoProcesamiento>
After executing the client generated by jaxws-maven-plugin:2.3 my ValidarCertificadoResponse has the next attributes:
ValidarCertificadoResponse.java
validarCertificadoReturn
peticion = null;
respuesta = null;
resultadoProcesamiento = null;
Do you find something wrong? I guess there are mistakes in the WSDL or maybe the plugin is not creating the headers properly?
Thanks.

I found a solution to my problem.
If we check the response SOAP message, we can see that there is only named one schema (http://ws.test), so every other element that belongs to the second schema cannot be transformed because jaxws doesn't find a match.
I cannot modify the web service because it isn't mine, so I adapted my wsdl to have only 1 schema. I guess it isn't the cleanest solution but it works.
Here is an example of how to do it:
BEFORE:
<element name="validarCertificadoResponse">
<complexType>
<sequence>
<element name="validarCertificadoReturn" type="tns1:MensajeSalida"/>
</sequence>
</complexType>
</element>
AFTER:
<xsd:element name="validarCertificadoResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="validarCertificadoReturn">
<!-- This is the content of tns1:MensajeSalida -->
<xsd:complexType>
<xsd:sequence>
<xsd:element name="peticion" type="xsd:string"/>
<!-- This is the content of tns1:Respuesta -->
<xsd:element name="respuesta">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="excepcion" nillable="true">
<!-- This is the content of tns1:Excepcion -->
<xsd:complexType>
<xsd:sequence>
<xsd:element name="codigoError" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="resultadoProcesamiento" nillable="true">
<!-- This is the content of tns1:ResultadoProcesamiento -->
<xsd:complexType>
<xsd:sequence>
<xsd:element name="resultado" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="versionMsg" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

Related

CXF : org.apache.cxf.interceptor.Fault: wrong number of arguments while invoking

I'm implementing a simple client using apache cxf and the codegen maven plugin (both release 3.1.11).
Here is my sample wsdl:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:webServiceTest" xmlns:s0="urn:webServiceTest" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema elementFormDefault="qualified" targetNamespace="urn:webServiceTest">
<xsd:element name="OpenTk" type="s0:InputMapping1"/>
<xsd:complexType name="InputMapping1">
<xsd:sequence>
<xsd:element minOccurs="0" name="ID_NOTIFICA" type="xsd:string"/>
<xsd:element minOccurs="0" name="ID_MESSAGGIO" type="xsd:string"/>
<xsd:element minOccurs="0" name="DATA_ID_NOTIFICA" type="xsd:dateTime"/>
<xsd:element minOccurs="0" name="DATA_ID_MESSAGGIO" type="xsd:dateTime"/>
<xsd:element minOccurs="0" name="ID_RISORSA" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="APERTURATKResponse" type="s0:OutputMapping1"/>
<xsd:complexType name="OutputMapping1">
<xsd:sequence>
<xsd:element minOccurs="0" name="CODICE" type="xsd:string"/>
<xsd:element minOccurs="0" name="DESCRIZIONE" type="xsd:string"/>
<xsd:element minOccurs="0" name="NOTE" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="AuthenticationInfo" type="s0:AuthenticationInfo"/>
<xsd:complexType name="AuthenticationInfo">
<xsd:sequence>
<xsd:element name="userName" type="xsd:string"/>
<xsd:element name="password" type="xsd:string"/>
<xsd:element minOccurs="0" name="authentication" type="xsd:string"/>
<xsd:element minOccurs="0" name="locale" type="xsd:string"/>
<xsd:element minOccurs="0" name="timeZone" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="OpenTkSoapOut">
<wsdl:part element="s0:APERTURATKResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="OpenTkSoapIn">
<wsdl:part element="s0:OpenTk" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="ARAuthenticate">
<wsdl:part element="s0:AuthenticationInfo" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="New_Port_0PortType">
<wsdl:operation name="OpenTk">
<wsdl:input message="s0:OpenTkSoapIn">
</wsdl:input>
<wsdl:output message="s0:OpenTkSoapOut">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="New_Port_0SoapBinding" type="s0:New_Port_0PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="OpenTk">
<soap:operation soapAction="urn:webServiceTest/OpenTk" style="document"/>
<wsdl:input>
<soap:header message="s0:ARAuthenticate" part="parameters" use="literal">
</soap:header>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="WebServicesFWCFFService">
<wsdl:port binding="s0:New_Port_0SoapBinding" name="New_Port_0Soap">
<soap:address location="http://localhost:9090/testService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I need to change client endpoint so I decided to use cxf.frontend feature. I created a simple Client and I used the api to set the address property.
Here is the code:
QName SERVICE = new QName("urn:webServiceTest", "WebServicesFWCFFService");
URL url = this.getClass().getClassLoader().getResource("testWsdl.wsdl").toURI().toURL();
NewPort0PortType portType = new WebServicesFWCFFService(url, SERVICE).getNewPort0Soap();
Client client = ClientProxy.getClient(portType);
client.getRequestContext().put(Message.ENDPOINT_ADDRESS,address);
Then inside my unit tests I try to invoke the service (the service created by codegen plugin) doing:
ClientTest client = new ClientTest();
Holder<String> code= new Holder<>();
Holder<String> description= new Holder<>();
Holder<String> notes= new Holder<>();
client.portType.openTk("12","",
null,null,"1",code, description, notes);
assertNotNull(notes.value);
assertNotNull(code.value);
but I receive a soap fault org.apache.cxf.binding.soap.SoapFault: wrong number of arguments while invoking public void it.test.cxf.impl.New_Port_0SoapImpl.openTk.
I found that the problem seems to be inside org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor and in particular when this interceptor create a WrapperHelper class using the method getHelperWrapper.
Then uses this wrapper to create the object using the ObjectFactory created by codegen plugin (createWrapperObject(objs);). This results in a new InputMappin1 object with all filds null.
Can someone explane me this behaviour and how I can avoid this? Do I need to implement some kind of custom interceptor or I'm missing some configuration?
I know this is an old question, but here is my 2 cents.
As you said, this seems a bug in cxf. I got the same error exposing a SOAP service with JBoss, using JAX-WS annotations in source code (my approach is contract-last, I start with an annotated java class and let cxf generate the service with its WSDL).
To overcome the problem, I specified the SOAP binding style as DOCUMENT, and parameters style as WRAPPED.
I used JAX WS annotation on the Service class:
#WebService
#SOAPBinding(
style = SOAPBinding.Style.DOCUMENT,
parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
public class MySoapService
You can read more details about SOAP bindings here.
Anyway, this changes the structure of XML messages, but cxf will handle all the details for you.

Cannot resolve the name ... to a(n) 'type definition' component

I want to import code from a WSDL file with wsimport, but i receiving this error below.
[WARNING] src-resolve: Cannot resolve the name 'impl:ArrayOf_tns1_IndicadorVO' to a(n) 'type definition' component.
Here's the WSDL file...
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://ws.cnmpind.cnmp.gov.br" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://ws.cnmpind.cnmp.gov.br" xmlns:intf="http://ws.cnmpind.cnmp.gov.br" xmlns:tns1="http://vo.ws.cnmpind.cnmp.gov.br" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="http://ws.cnmpind.cnmp.gov.br" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://vo.ws.cnmpind.cnmp.gov.br"/>
<element name="getQuestionariosDisponiveis">
<complexType>
<sequence>
<element name="email" type="xsd:string"/>
<element name="senha" type="xsd:string"/>
<element name="dataInicio" type="xsd:string"/>
<element name="dataFinal" type="xsd:string"/>
<element name="areaAtuacao" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="getQuestionariosDisponiveisResponse">
<complexType>
<sequence>
<element maxOccurs="unbounded" name="getQuestionariosDisponiveisReturn" type="tns1:QuestionarioVO"/>
</sequence>
</complexType>
</element>
<complexType name="ArrayOf_tns1_IndicadorVO">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="item" type="tns1:IndicadorVO"/>
</sequence>
</complexType>
<element name="salvaRespostasQuestionarios">
<complexType>
<sequence>
<element name="email" type="xsd:string"/>
<element name="senha" type="xsd:string"/>
<element name="dataInicio" type="xsd:string"/>
<element name="dataFinal" type="xsd:string"/>
<element name="areaAtuacao" type="xsd:string"/>
<element maxOccurs="unbounded" name="questionarios" type="tns1:QuestionarioVO"/>
</sequence>
</complexType>
</element>
<element name="salvaRespostasQuestionariosResponse">
<complexType/>
</element>
</schema>
<schema elementFormDefault="qualified" targetNamespace="http://vo.ws.cnmpind.cnmp.gov.br" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://ws.cnmpind.cnmp.gov.br"/>
<complexType name="IndicadorVO">
<sequence>
<element name="descricaoDescritor" nillable="true" type="xsd:string"/>
<element name="id" type="xsd:long"/>
<element name="idDescritor" type="xsd:int"/>
<element name="idIndicadorPai" type="xsd:long"/>
<element name="idQuestionario" type="xsd:long"/>
<element name="nomeDescritor" nillable="true" type="xsd:string"/>
<element name="ordem" type="xsd:int"/>
<element name="tamanhoDescritor" nillable="true" type="xsd:decimal"/>
<element name="tipoDescritor" nillable="true" type="xsd:string"/>
<element name="valor" nillable="true" type="xsd:decimal"/>
</sequence>
</complexType>
<complexType name="QuestionarioVO">
<sequence>
<element name="aberto" type="xsd:boolean"/>
<element name="dataAtualizacao" nillable="true" type="xsd:string"/>
<element name="dataInicio" nillable="true" type="xsd:string"/>
<element name="dataTermino" nillable="true" type="xsd:string"/>
<element name="descricaoArea" nillable="true" type="xsd:string"/>
<element name="id" type="xsd:long"/>
<element name="idArea" type="xsd:int"/>
<element name="idUnidade" type="xsd:int"/>
<element name="indicadores" nillable="true" type="impl:ArrayOf_tns1_IndicadorVO"/>
<element name="nomeArea" nillable="true" type="xsd:string"/>
<element name="nomeUnidade" nillable="true" type="xsd:string"/>
<element name="nomeUsuarioAtualizacao" nillable="true" type="xsd:string"/>
<element name="siglaUnidade" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="salvaRespostasQuestionariosResponse">
<wsdl:part element="impl:salvaRespostasQuestionariosResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="getQuestionariosDisponiveisResponse">
<wsdl:part element="impl:getQuestionariosDisponiveisResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="getQuestionariosDisponiveisRequest">
<wsdl:part element="impl:getQuestionariosDisponiveis" name="parameters"/>
</wsdl:message>
<wsdl:message name="salvaRespostasQuestionariosRequest">
<wsdl:part element="impl:salvaRespostasQuestionarios" name="parameters"/>
</wsdl:message>
<wsdl:portType name="QuestionarioWS">
<wsdl:operation name="getQuestionariosDisponiveis">
<wsdl:input message="impl:getQuestionariosDisponiveisRequest" name="getQuestionariosDisponiveisRequest"/>
<wsdl:output message="impl:getQuestionariosDisponiveisResponse" name="getQuestionariosDisponiveisResponse"/>
</wsdl:operation>
<wsdl:operation name="salvaRespostasQuestionarios">
<wsdl:input message="impl:salvaRespostasQuestionariosRequest" name="salvaRespostasQuestionariosRequest"/>
<wsdl:output message="impl:salvaRespostasQuestionariosResponse" name="salvaRespostasQuestionariosResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="QuestionarioWSSoapBinding" type="impl:QuestionarioWS">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getQuestionariosDisponiveis">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getQuestionariosDisponiveisRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getQuestionariosDisponiveisResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="salvaRespostasQuestionarios">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="salvaRespostasQuestionariosRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="salvaRespostasQuestionariosResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="QuestionarioWSService">
<wsdl:port binding="impl:QuestionarioWSSoapBinding" name="QuestionarioWS">
<wsdlsoap:address location="http://aplicativos.cnmp.gov.br/cnmpind/services/QuestionarioWS"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Someone can give me some light? Thanks!
EDIT 1:
This is just a warning. The true error is
package-info.java:1: error: error while writing package-info: could
not create parent directories
#javax.xml.bind.annotation.XmlSchema(namespace =
"http://ws.cnmpind.cnmp.gov.br", elementFormDefault =
javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
So, the code was generated, but the error happens when compiling.
Its seems to be a WSIMPORT bug, i don't know.
To solve the problem, I used the param "-Xnocompile" to force WSIMPORT only generate the code whithout compiling.
After that, i compiled the code by command line with javac and put the classes into a .jar
I added the .jar to the project and everything are running fine.

CXF wsdl2java listwrapper in wsdl should be unwrapped

I'm currently updating a old axis wsclient to a cxf(jaxb databinding) client,
now there are differences, how list/array are handled.
Let me explain that on an example:
wsdl
<xsd:complexType name="ArrayOfString">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="string" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
which is in a other complexType
<xsd:complexType name="CustomParameter">
<xsd:sequence>
<xsd:element minOccurs="0" name="values" nillable="true" type="tns:ArrayOfString"/>
</xsd:sequence>
</xsd:complexType>
now when trying to access this attribute in cxf it is needed to additionally get the value from the list-wrapper
CustomParameter.getValues().getString(); // returns List<String>
Axis does afaik unwrap this automatically that you got the array only with
CustomParameter.getValues() // returns String[]
My question is, is this possible to do this in cxf?
A part of my wsdl:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://ws611.webservice.adapters.company.de" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws611.webservice.adapters.company.de" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns2="http://usermanagement.ws611.webservice.company.de"
xmlns:ns1="http://ws611.webservice.company.de" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding">
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://ws611.webservice.company.de">
<xsd:complexType name="AuthenticationToken">
<xsd:sequence>
<xsd:element minOccurs="0" name="password" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="timestamp" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="username" nillable="true" type="xsd:string"/>
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
</xsd:schema>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://ws611.webservice.adapters.company.de">
<xsd:element name="getAllUsers">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="ns1:AuthenticationToken"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="getAllUsersResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="ns2:ArrayOfUser"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://usermanagement.ws611.webservice.company.de">
<xsd:complexType name="ArrayOfUser">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="User" nillable="true" type="ns2:User"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="User">
<xsd:sequence>
<xsd:element minOccurs="0" name="name" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="groups" nillable="true" type="ns2:ArrayOfGroup"/>
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
<xsd:complexType name="ArrayOfGroup">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="Group" nillable="true" type="ns2:Group"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Group">
<xsd:sequence>
<xsd:element minOccurs="0" name="name" nillable="true" type="xsd:string"/>
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="getAllUsersRequest">
<wsdl:part name="parameters" element="tns:getAllUsers">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getAllUsersResponse">
<wsdl:part name="parameters" element="tns:getAllUsersResponse">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="UserManagementPortType">
<wsdl:operation name="getAllUsers">
<wsdl:input name="getAllUsersRequest" message="tns:getAllUsersRequest">
</wsdl:input>
<wsdl:output name="getAllUsersResponse" message="tns:getAllUsersResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="UserManagementHttpBinding" type="tns:UserManagementPortType">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getAllUsers">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getAllUsersRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getAllUsersResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="UserManagement">
<wsdl:port name="UserManagementHttpPort" binding="tns:UserManagementHttpBinding">
<wsdlsoap:address location="http://localhost:8080/test/webservice/ws611/UserManagement"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
It is possible to get the cxf-codegen-plugin to generate model classes that automatically hide XML element wrapper classes.
There are three things you need to use:
A custom JAXB binding file that suppresses usage of JAXBElement
For any PortTypes, a custom JAXWS binding file that makes sure to use your request and response classes directly
The jaxb-xew-plugin to generate #XmlElementWrapper annotations, which is the JAXB annotation for designating lists as wrapped
Here is what the custom JAXB binding file should look like:
<jaxb:bindings version="2.1" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<jaxb:globalBindings generateElementProperty="false"/>
</jaxb:bindings>
Here is what the custom JAXWS binding file should look like:
<jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
</jaxws:bindings>
Here is a sample working usage of the cxf-codegen-plugin using JAXB and JAXWS binding files and the jaxb-xew-plugin:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.1.4</version>
<executions>
<execution>
<id>generate-client</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/sample.wsdl</wsdl>
<bindingFiles>
<bindingFile>${basedir}/src/main/resources/jaxbBinding.xml</bindingFile>
<bindingFile>${basedir}/src/main/resources/jaxwsBinding.xml</bindingFile>
</bindingFiles>
<extraargs>
<extraarg>-xjc-Xxew</extraarg>
<extraarg>-xjc-Xxew:summary
${project.build.outputDirectory}/../xew-summary.txt
</extraarg>
<extraarg>-xjc-Xxew:instantiate lazy</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.jaxb-xew-plugin</groupId>
<artifactId>jaxb-xew-plugin</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>2.2.11</version>
</dependency>
</dependencies>
</plugin>
This configuration will generate the following on the schema provided in the question:
CustomParameter.getValues() // returns List<String>
Note that this does NOT return a String[]. You could get the cxf-codegen-plugin to use a String[] instead of a List<String> by adding a collectionType="indexed" attribute to your globalBindings, but currently the jaxb-xew-plugin only supports Collection types and not arrays.

How to pass null value to Document Literal SOAP Request

Hi,
I am passing the null value for the resourcekey in the SOAP Request as below.
<urn:createNetwork>
<net:resourceIdentityInfo>
<api:resourceKey ></api:resourceKey>
<api:resourceName>TEST2</api:resourceName>
<api:resourceType>NETWORK</api:resourceType>
</net:resourceIdentityInfo>
</urn:createNetwork>
The sample WSDL file for this request is as below:
<wsdl:operation name="createNetwork">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="createNetworkRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="createNetworkResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<element name="createNetwork">
<complexType>
<sequence>
<element name="in0" type="tns5:NetworkInfo"/>
</sequence>
</complexType>
</element>
<element name="createNetworkResponse">
<complexType>
<sequence>
<element name="createNetworkReturn" type="tns2:ResourceIdentityInfo"/>
</sequence>
</complexType>
</element>
<wsdl:message name="createNetworkRequest">
<wsdl:part element="intf:createNetwork" name="parameters">
</wsdl:part>
</wsdl:message>
<complexType name="NetworkInfo">
<sequence>
<element name="comments" nillable="true" type="impl:ArrayOf_xsd_anyType"/>
<element name="description" nillable="true" type="xsd:string"/>
<element name="dnsDomainName" nillable="true" type="xsd:string"/>
<element name="documentUrls" nillable="true" type="impl:ArrayOf_xsd_anyType"/>
<element name="resourceIdentityInfo" nillable="true" type="tns2:ResourceIdentityInfo"/>
</sequence>
</complexType>
<complexType name="ResourceIdentityInfo">
<sequence>
<element name="resourceKey" nillable="true" type="xsd:string"/>
<element name="resourceName" nillable="true" type="xsd:string"/>
<element name="resourceType" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
I have declared as nillable=true in all the places.
If i pass the resourcekey as empty, in SOAP UI I am getting null pointer exception.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>java.lang.NullPointerException</faultstring>
<detail>
<ns1:hostname xmlns:ns1="http://xml.apache.org/axis/">linbgg244.lss.emc.com</ns1:hostname>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
I have tried with
<api:resourceKey xsi:nil="true" ></api:resourceKey>
The same null pointer exception is getting.
Could you please guide to resolve the issue?
Thanks in advance.
I don't think you have to pass null here. AFAIK, the webservice code is throwing the NullPointerException during processing of the SOAP request. Try to identify why is that ? and do a null check or make changes in the logic to prevent it.

Specify order of elements in a SOAP response using java

I have a web service that returns a dataset object that contains the current weather forecast along with 0 or more weather alerts for a county/state. The dataset object just contains a Weather object and an array of Alerts objects. One of the clients of this would like to have it so the response gives the weather first instead of the alerts. Is there a way to specify the order of the response elements? I thought I could just change the WSDL to map out the weather first then the alerts, but that didn't do anything.
Here's the generic WSDL sheet:
(well, it showed formatted in the preview but not after posting... how can I post formatted XML on here? I tried using back-ticks as well as pre and code).
<wsdl:definitions ...>
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="http://ws.sample.com" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://objects.sample.com"/>
<element name="getAll">
<complexType>
<sequence>
<element name="county" type="xsd:string"/>
<element name="state" type="xsd:string"/>
<element name="latitude" type="xsd:double"/>
<element name="longitude" type="xsd:double"/>
</sequence>
</complexType>
</element>
<element name="getAllResponse">
<complexType>
<sequence>
<element name="getAllReturn" type="tns1:DataSet"/>
</sequence>
</complexType>
</element>
<complexType name="ArrayOf_tns1_Alert">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="item" type="tns1:Alert"/>
</sequence>
</complexType>
</schema>
<schema elementFormDefault="qualified" targetNamespace="http://objects.sample.com" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://ws.sample.com"/>
<complexType name="Alert">
<sequence>
<element name="county" nillable="true" type="xsd:string"/>
<element name="endDate" nillable="true" type="xsd:dateTime"/>
<element name="locationCode" nillable="true" type="xsd:string"/>
<element name="startDate" nillable="true" type="xsd:dateTime"/>
<element name="state" nillable="true" type="xsd:string"/>
<element name="title" nillable="true" type="xsd:string"/>
<element name="warning" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
<complexType name="Weather">
<sequence>
<element name="chancePrecipitation" type="xsd:int"/>
<element name="period" nillable="true" type="xsd:string"/>
<element name="skyConditions" nillable="true" type="xsd:string"/>
<element name="temperature" type="xsd:int"/>
<element name="temperatureType" nillable="true" type="xsd:string"/>
<element name="temperatureUnit" nillable="true" type="xsd:string"/>
<element name="windDirection" nillable="true" type="xsd:string"/>
<element name="windSpeed" type="xsd:int"/>
<element name="windUnit" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
<complexType name="DataSet">
<sequence>
<element name="weather" nillable="true" type="tns1:Weather"/>
<element name="alert" nillable="true" type="impl:ArrayOf_tns1_Alert"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="getAllResponse">
<wsdl:part element="impl:getAllResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="getAllRequest">
<wsdl:part element="impl:getAll" name="parameters"/>
</wsdl:message>
<wsdl:portType name="TSTWeather">
<wsdl:operation name="getAll">
<wsdl:input message="impl:getAllRequest" name="getAllRequest"/>
<wsdl:output message="impl:getAllResponse" name="getAllResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TSTWeatherSoapBinding" type="impl:TSTWeather">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getAll">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getAllRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getAllResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TSTWeatherService">
<wsdl:port binding="impl:TSTWeatherSoapBinding" name="TSTWeather">
<wsdlsoap:address location="http://localhost:8282/Services/service/TSTWeather"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I don't see how I could specify the order of my service response.
In many cases, just changing the WSDL does not change the service, and it's the service that determines the order of the elements in the XML.
We can change the order by adding JAXB annotations in the particular java file.
For example: #XmlType(propOrder = {"x", "y", "z"})

Categories