Unmarshall exception for SOAP done with contract-first Spring-WS - spring

I am trying to code my first SOAP web service.
I am getting the SOAP response Unmarshall failure
which is the response i mapped to org.springframework.oxm.UnmarshallingFailureException.
I have configured Spring to use Castor (un)marshaller.
Problem is i don't know how to find a more specific cause.
public class SentenceRequest {
public SentenceRequest() {}
private List<String> words = new ArrayList<String>();
public List<String> getWords() {
return words;
}
public void setWords(List<String> words) {
this.words = words;
}
public class SentenceResponse {
private String sentence;
public SentenceResponse() {}
public SentenceResponse(String sen) {
sentence = sen;
}
public String getSentence() {
return sentence;
}
public void setSentence(String sentence) {
this.sentence = sentence;
}
the castor mapping:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapping PUBLIC
"-//EXOLAB/Castor Object Mapping DTD Version 1.0//EN"
"http://castor.exolab.org/mapping.dtd">
<mapping xmlns="http://castor.exolab.org/">
<class name="ro.soapservice2.SentenceRequest">
<map-to xml="SentenceRequest" ns-uri="sentence" ns-prefix="s" />
<field name="words" collection="arraylist" type="java.util.List" required="true">
<bind-xml name="word" node="element"></bind-xml>
</field>
</class>
<class name="ro.soapservice2.SentenceResponse">
<map-to xml="SentenceResponse" ns-uri="sentence" ns-prefix="s" />
<field name="sentence" type="java.lang.String" required="true">
<bind-xml name="sentence" node="element" />
</field>
</class>
</mapping>
the schema (generated with Trang.jar based on two input XML files):
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="sentence" xmlns:s="sentence">
<xs:element name="SentenceRequest">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="s:word"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="word" type="xs:string"/>
<xs:element name="SentenceResponse">
<xs:complexType>
<xs:sequence>
<xs:element ref="s:sentence"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="sentence" type="xs:string"/>
</xs:schema>
and the WSDL Spring generates:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="sentence" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="sentence" targetNamespace="sentence">
<wsdl:types>
<xs:schema xmlns:s="sentence" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="sentence">
<xs:element name="SentenceRequest">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="s:word"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="word" type="xs:string"/>
<xs:element name="SentenceResponse">
<xs:complexType>
<xs:sequence>
<xs:element ref="s:sentence"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="sentence" type="xs:string"/>
</xs:schema>
</wsdl:types>
<wsdl:message name="SentenceResponse">
<wsdl:part element="tns:SentenceResponse" name="SentenceResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="SentenceRequest">
<wsdl:part element="tns:SentenceRequest" name="SentenceRequest">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="Sentence">
<wsdl:operation name="Sentence">
<wsdl:input message="tns:SentenceRequest" name="SentenceRequest">
</wsdl:input>
<wsdl:output message="tns:SentenceResponse" name="SentenceResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SentenceSoap11" type="tns:Sentence">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Sentence">
<soap:operation soapAction=""/>
<wsdl:input name="SentenceRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="SentenceResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SentenceService">
<wsdl:port binding="tns:SentenceSoap11" name="SentenceSoap11">
<soap:address location="http://localhost:8080/soapservice2/services"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
the SOAP request i make:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sen="sentence">
<soapenv:Header/>
<soapenv:Body>
<sen:SentenceRequest>
<!--1 or more repetitions:-->
<sen:word>asd</sen:word>
</sen:SentenceRequest>
</soapenv:Body>
</soapenv:Envelope>

Solved!
First i replaced my exception resolver from
org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver
to
org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver
which puts back in the SOAP response the real exception that was thrown.
Then i saw the problem was at the Castor xml mapping file:
changed from
<field name="words" collection="arraylist" type="java.util.List" required="true">
<bind-xml name="word" node="element"></bind-xml>
</field>
to
<field name="words" collection="arraylist" type="java.lang.String" required="true">
<bind-xml name="word" node="element"></bind-xml>
</field>

Related

SOAP mode wsdl : How to post and receive data in the format provided by wsdl

I am learning the soap webservices for which a wsdl file has been provided. I work in PHP (laravel 9 and I did not use a soap package because I want to better understand the native) I want to be able to post and receive data in the format recommended by the wsdl. Except that when I make a test on the code that I implemented and I make a
var_dump($client->__getLastRequest()) and var_dump( $client->__soapCall('ombRequest', $params))
For the request I don't see my inputs and the output always returns me null
I present below the wsdl code for a function so as not to be very long.
I would like to send the inputs of type AccountToWalletTransfer and have the output of type AccountToWalletTransferResponse as specified by the wsdl file
partner.wsdl
<wsdl:definitions name="IB2WService" targetNamespace="http://localhost/om-integration/public/wsld/bankapi/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://localhost/om-integration/public/wsld/bankapi/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xs:schema targetNamespace="http://localhost/om-integration/public/wsld/bankapi/" version="1.0" xmlns:tns="http://localhost/om-integration/public/wsld/bankapi/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="HeaderRequest">
<xs:sequence>
<xs:element name="operatorCode" type="xs:string" />
<xs:element name="requestId" type="xs:string" />
<xs:element name="requestToken" type="xs:string" />
<xs:element name="requestType" type="xs:string" />
<xs:element name="affiliateCode" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="HeaderResponse">
<xs:sequence>
<xs:element name="operatorCode" type="xs:string" />
<xs:element name="requestId" type="xs:string" />
<xs:element name="affiliateCode" type="xs:string" />
<xs:element name="responseCode" type="xs:string" />
<xs:element name="responseMessage" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
<xs:schema elementFormDefault="unqualified" targetNamespace="http://localhost/om-integration/public/wsld/bankapi/" version="1.0" xmlns:ns1="http://localhost/om-integration/public/wsld/bankapi/" xmlns:tns="http://localhost/om-integration/public/wsld/bankapi/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="AccountToWalletTransfer" type="tns:AccountToWalletTransfer" />
<xs:element name="AccountToWalletTransferResponse" type="tns:AccountToWalletTransferResponse" />
<xs:complexType name="AccountToWalletTransfer">
<xs:sequence>
<xs:element minOccurs="0" name="MobileTransferRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="mmHeaderInfo" type="ns1:HeaderRequest" />
<xs:element name="externalRefNo" type="xs:string" />
<xs:element name="mobileNo" type="xs:string" />
<xs:element name="mobileName" type="xs:string" />
<xs:element name="mobileAlias" type="xs:string" />
<xs:element name="accountNo" type="xs:string" />
<xs:element name="accountAlias" type="xs:string" />
<xs:element name="accountName" type="xs:string" />
<xs:element name="transferDescription" type="xs:string" />
<xs:element name="ccy" type="xs:string" />
<xs:element name="amount" type="xs:double" />
<xs:element name="charge" type="xs:double" />
<xs:element name="tranDate" type="xs:date" />
<xs:element name="udf1" type="xs:string" />
<xs:element name="udf2" type="xs:string" />
<xs:element name="udf3" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AccountToWalletTransferResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return">
<xs:complexType>
<xs:sequence>
<xs:element name="mmHeaderInfo" type="ns1:HeaderResponse" />
<xs:element name="externalRefNo" type="xs:string" />
<xs:element name="CBAReferenceNo" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="AccountToWalletTransfer">
<wsdl:part element="tns:AccountToWalletTransfer" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="AccountToWalletTransferResponse">
<wsdl:part element="tns:AccountToWalletTransferResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="B2WServices">
<wsdl:operation name="AccountToWalletTransfer">
<wsdl:input message="tns:AccountToWalletTransfer" name="AccountToWalletTransfer"></wsdl:input>
<wsdl:output message="tns:AccountToWalletTransferResponse" name="AccountToWalletTransferResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="IB2WServiceSoapBinding" type="tns:B2WServices">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="AccountToWalletTransfer">
<soap:operation soapAction="http://localhost/om-integration/public/AccountToWalletTransfer" style="document" />
<wsdl:input name="AccountToWalletTransfer">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="AccountToWalletTransferResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="IB2WService">
<wsdl:port binding="tns:IB2WServiceSoapBinding" name="B2WServicesPort">
<soap:address location="EXPOSED_URL" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
My inputs_____________
$client->__setLocation('http://localhost/om-integration/public/server');
$params = [
'AccountToWalletTransfer ' =>[
'operatorCode' => 'MODSSEZZZDD',
'requestId' => 'AZASSRFF',
'requestToken' => 'ea9ce3f18ecc96bbfdbd72800dc0f0b04ada7e09672dcb289346d4fd47',
'requestType' => 'A2W',
'affiliateCode' => 'EML',
'externalRefNo' => '',
'mobileNo' => '',
'mobileName' => '',
'mobileAlias' => '',
'accountNo' => '',
'accountAlias' => 'BICBICBI0000000001300',
'accountName' => '',
'transferDescription' => '',
'ccy' => 'EURO',
'amount' => '1000',
'charge' => '0',
'tranDate' => '2022-09-22',
'udf1' => '',
'udf2' => '',
'udf3' => '',
]
];
$response = $client->__soapCall('AccountToWalletTransfer', $params);
Server___________
if($request){
$server = new SoapServer(asset('wsdl/bankapi/partner.wsdl'), ['uri'=>'http://localhost/om-integration/public/server']);
$server->setClass('App\Soap\Services');
$server->handle();
}
else
return false;
Response______________
$response = new AccountToWalletTransferResponse('RETEDDFZSDD',
$params['requestId'],
$params['affiliateCode'],
'200',
'Success',
$params['requestId'],
'FKGI22541'
);
return $response;

Spring WS is not generating wsdl operations for all the public methods in the Endpoint class

I have a Spring endpoint class with two public methods. But when Spring is auto-generating the wsdl it doesn't include the second public method. Could you pleas let me know what is wrong and what needs to be done. I am using Spring 4.3 and below are the classes.
Configuration class
#EnableWs
#Configuration
public class SoapServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "policies")
public DefaultWsdl11Definition policyserviceWsdl11Definition(#Autowired #Qualifier("swissSchema") XsdSchema swissSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("PoliciesPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://www.testcomp.com/iaworkflow/soapservice");
wsdl11Definition.setSchema(swissSchema);
return wsdl11Definition;
}
#Bean(name = "bankservice")
public DefaultWsdl11Definition bankServiceWsdlDefinition(#Autowired #Qualifier("bankSchema")XsdSchema bankSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("BankAPIPort");
wsdl11Definition.setLocationUri("/ws/bankapi");
wsdl11Definition.setTargetNamespace("http://www.testcomp.com/consumer/bankservice/soapservice");
wsdl11Definition.setSchema(bankSchema);
return wsdl11Definition;
}
#Bean
#Qualifier("bankSchema")
public XsdSchema bankSchema() {
return new SimpleXsdSchema(new ClassPathResource("bankservice.xsd"));
}
#Bean
#Qualifier("swissSchema")
public XsdSchema swissSchema() {
return new SimpleXsdSchema(new ClassPathResource("policylookup.xsd"));
}
}
Endpoint
#Endpoint
public class BankingServiceEndpoint {
private static final String NAMESPACE_URI = "http://www.testcomp.com/consumer/bankservice/soapservice";
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "BankInfoSearchRequest")
#ResponsePayload
public BankInfoSearchResponse getBankInfo(#RequestPayload BankInfoSearchRequest request) {
BankInfoSearchResponse response = createDummyResponse(request.getPolicyNumber(),request.getLimit());
return response;
}
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "BankVerificationRequest")
#ResponsePayload
public BankVerificationResponse verifyBankInformation(#RequestPayload BankVerificationRequest request) {
return BankVerificationResponse.builder().build();
}
}
Generated WSDL
<?xml version="1.0" encoding="UTF-8" standalone="no"?><wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="http://www.testcomp.com/consumer/bankservice/soapservice" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.testcomp.com/consumer/bankservice/soapservice" targetNamespace="http://www.testcomp.com/consumer/bankservice/soapservice">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.testcomp.com/consumer/bankservice/soapservice" version="1.0">
<xs:element name="BankInfoSearchRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="policyNumber" type="xs:string"/>
<xs:element name="limit" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="BankInfoSearchResponse">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="1" name="policyNumber" nillable="false" type="xs:string"/>
<xs:element name="bankdatas" type="tns:BankDatas"/>
<xs:element maxOccurs="1" name="error" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="BankDatas">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="bankinfo" type="tns:BankInfo"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BankInfo">
<xs:sequence>
<xs:element name="AccountNumber" type="xs:string"/>
<xs:element name="RoutingNumber" type="xs:string"/>
<xs:element name="BankName" type="xs:string"/>
<xs:element name="VerificationDescription" type="xs:string"/>
<xs:element name="VerificationCode" type="xs:string"/>
<xs:element name="Verified" type="xs:boolean"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BankVerificationRequest">
<xs:sequence>
<xs:element maxOccurs="1" name="PolicyOwnerInformation" type="tns:PolicyOwnerInformation"/>
<xs:element maxOccurs="1" name="BankInfo" type="tns:BankInfo"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PolicyOwnerInformation">
<xs:sequence>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="MiddleName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="SSN" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BankVerificationResponse">
<xs:sequence>
<xs:element maxOccurs="1" name="PolicyOwnerInformation" type="tns:PolicyOwnerInformation"/>
<xs:element maxOccurs="1" name="Bankinfo" type="tns:BankInfo"/>
<xs:element name="BankVerificationTransactionId" type="xs:string"/>
<xs:element name="ItemReferenceId" type="xs:string"/>
<xs:element name="SubmittedBy" type="xs:string"/>
<xs:element name="VerificationResponse" type="xs:string"/>
<xs:element name="VerificationStatus" type="xs:string"/>
<xs:element name="BankVerificationTransactionType" type="xs:string"/>
<xs:element name="Created" type="xs:string"/>
<xs:element name="Success" type="xs:string"/>
<xs:element name="Error" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="BankInfoSearchResponse">
<wsdl:part element="tns:BankInfoSearchResponse" name="BankInfoSearchResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="BankInfoSearchRequest">
<wsdl:part element="tns:BankInfoSearchRequest" name="BankInfoSearchRequest">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="BankAPIPort">
<wsdl:operation name="BankInfoSearch">
<wsdl:input message="tns:BankInfoSearchRequest" name="BankInfoSearchRequest">
</wsdl:input>
<wsdl:output message="tns:BankInfoSearchResponse" name="BankInfoSearchResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BankAPIPortSoap11" type="tns:BankAPIPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="BankInfoSearch">
<soap:operation soapAction=""/>
<wsdl:input name="BankInfoSearchRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="BankInfoSearchResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="BankAPIPortService">
<wsdl:port binding="tns:BankAPIPortSoap11" name="BankAPIPortSoap11">
<soap:address location="http://localhost:9080/workflowintg/ws/bankapi"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I figured out the issue. There was a problem in the XSD. I declared the root element as xs:complexType instead of xs:element.

Apache CXF and Apache Camel: the given SOAPAction does not match an operation

I'm trying to walk through the Camel Report Incident tutorial and am stuck at the end of part 5. When I try to run the unit test it fails with the message The given SOAPAction http://reportincident.example.camel.apache.org/ReportIncident does not match an operation.
I saw a similar question where the problem was that the declared soapAction attribute on the WSDL file had a different value from the actual SOAP request. This does not seem to be my case. Any ideas about what is going wrong? Thanks in advance.
reportIncident.wsdl
<?xml version="1.0" encoding="ISO-8859-1"?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://reportincident.example.camel.apache.org"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://reportincident.example.camel.apache.org">
<!-- Type definitions for input- and output parameters for webservice -->
<wsdl:types>
<xs:schema targetNamespace="http://reportincident.example.camel.apache.org">
<xs:element name="inputReportIncident">
<xs:complexType name="inputReportIncident">
<xs:sequence>
<xs:element type="xs:string" name="incidentId" />
<xs:element type="xs:string" name="incidentDate" />
<xs:element type="xs:string" name="givenName" />
<xs:element type="xs:string" name="familyName" />
<xs:element type="xs:string" name="summary" />
<xs:element type="xs:string" name="details" />
<xs:element type="xs:string" name="email" />
<xs:element type="xs:string" name="phone" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="outputReportIncident">
<xs:complexType name="outputReportIncident">
<xs:sequence>
<xs:element type="xs:string" name="code" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<!-- Message definitions for input and output -->
<wsdl:message name="inputReportIncident">
<wsdl:part name="parameters" element="tns:inputReportIncident" />
</wsdl:message>
<wsdl:message name="outputReportIncident">
<wsdl:part name="parameters" element="tns:outputReportIncident" />
</wsdl:message>
<!-- Port (interface) definitions -->
<wsdl:portType name="ReportIncidentEndpoint">
<wsdl:operation name="ReportIncident">
<wsdl:input message="tns:inputReportIncident" />
<wsdl:output message="tns:outputReportIncident" />
</wsdl:operation>
</wsdl:portType>
<!-- Port bindings to transports and encoding - HTTP, document literal
encoding is used -->
<wsdl:binding name="ReportIncidentBinding" type="tns:ReportIncidentEndpoint">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="ReportIncident">
<soap:operation soapAction="http://reportincident.example.camel.apache.org/ReportIncident" style="document" />
<wsdl:input>
<soap:body parts="parameters" use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body parts="parameters" use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!-- Service definition -->
<wsdl:service name="ReportIncidentService">
<wsdl:port name="ReportIncidentPort" binding="tns:ReportIncidentBinding">
<soap:address location="http://reportincident.example.camel.apache.org" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
route definition (inside a RouteBuilder subclass)
OutputReportIncident ok = new OutputReportIncident();
ok.setCode("0");
// endpoint to our CXF webservice
String cxfEndpoint = "cxf://http://localhost:8080/part-five/webservices/incident"
+ "?serviceClass=org.apache.camel.example.reportincident.ReportIncidentEndpoint"
+ "&wsdlURL=reportIncident.wsdl";
// first part from the webservice -> file backup
from(cxfEndpoint)
// we need to convert the CXF payload to InputReportIncident that FilenameGenerator and velocity expects
.convertBodyTo(InputReportIncident.class)
// then set the file name using the FilenameGenerator bean
.setHeader("CamelFileName", BeanLanguage.bean(FilenameGenerator.class, "generateFilename"))
// transform the message using velocity to generate the mail message
.to("velocity:mailBody.vm")
// and store the file
.to("file://target/subfolder")
// return OK as response
// usando transformaĆ§Ć£o!
.transform(constant(ok));
pom.xml (wsdl2java is used to generate Java files from WSDL)
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.13.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated/src/main/java</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/reportIncident.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
test code
package org.apache.camel.example.reportincident;
import static org.junit.Assert.*;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Test;
import org.jvnet.mock_javamail.Mailbox;
public class ReportIncidentRoutesTest {
// should be the same address as we have in our route
private static String ADDRESS = "http://localhost:8080/part-five/webservices/incident";
private CamelContext context;
#Test
public void testRendportIncident() throws Exception {
// start camel
startCamel();
// assert mailbox is empty before starting
Mailbox inbox = Mailbox.get("incident#mycompany.com");
assertEquals("Should not have mails", 0, inbox.size());
// create input parameter
InputReportIncident input = new InputReportIncident();
input.setIncidentId("123");
input.setIncidentDate("2008-08-18");
input.setGivenName("Claus");
input.setFamilyName("Ibsen");
input.setSummary("Bla");
input.setDetails("Bla bla");
input.setEmail("davsclaus#apache.org");
input.setPhone("0045 2962 7576");
// create the webservice client and send the request
ReportIncidentEndpoint client = createCXFClient();
OutputReportIncident out = client.reportIncident(input);
// assert we got a OK back
assertEquals("0", out.getCode());
// let some time pass to allow Camel to pickup the file and send it as an email
Thread.sleep(3000);
// assert mail box
assertEquals("Should have got 1 mail", 1, inbox.size());
// stop camel
context.stop();
}
private void startCamel() throws Exception {
context = new DefaultCamelContext();
context.disableJMX();
context.addRoutes(new ReportIncidentRoutes());
context.start();
}
private ReportIncidentEndpoint createCXFClient() {
// we use CXF to create a client for us as its easier than JAXWS and works
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(ReportIncidentEndpoint.class);
factory.setAddress(ADDRESS);
return (ReportIncidentEndpoint) factory.create();
}
}
I think you just need to pass the WSDL url to the JaxWsProxyFactoryBean and it can take care of the soap action for you.
Please change the ReportIncidentRoutesTest.createCXFClient() like this
private ReportIncidentEndpoint createCXFClient() {
// we use CXF to create a client for us as its easier than JAXWS and works
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(ReportIncidentEndpoint.class);
factory.setWsdlURL("reportIncident.wsdl");
factory.setAddress(ADDRESS);
return (ReportIncidentEndpoint) factory.create();
}

case-insensitive key in xsd

I have an XSD embedded into an XML like this:
<Replacements>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Replacements">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Replace" />
</xs:sequence>
</xs:complexType>
<xs:key name="ReplaceKey">
<xs:selector xpath="./Replace"/>
<xs:field xpath="#old"/>
</xs:key>
</xs:element>
<xs:element name="Replace">
<xs:complexType>
<xs:attribute name="old" type="AnythingButLowerCase" use="required" />
<xs:attribute name="new" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:simpleType name="AnythingButLowerCase">
<xs:restriction base="xs:string">
<xs:pattern value="[^a-z]+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
<Replace old="A1020____9" new="A1020"/>
<Replace old="a1020____9" new="A1020"/>
</Replacements>
I've used xs:key to define a unique-key on "old" attribute of Replace elements.
my problem is I want this key to be CASE-INSENSITIVE.
I've read so many documents indicating I can use xsd functions like upper-case or translate to solve this, but if I write something like
<xs:field xpath="upper-case(#old)"/>
VS2010 gives me a warning like this:
'upper-case(#old)' is an invalid XPath for selector or field.
What is it I'm doing wrong?
Thanks :)
The correct XPath function is "upper-case", not "upper case". Just add in the hyphen.
OK!
I got that!
Using functions in an xpath for a xs:field is not allowed.
The workaround for what I was seeking is to define a simpleType and put a restriction there not allowing lower-case letters.
Something like this:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Replacements>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Replacements">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Replace" />
</xs:sequence>
</xs:complexType>
<xs:key name="ReplaceKey">
<xs:selector xpath="./Replace"/>
<xs:field xpath="#old"/>
</xs:key>
</xs:element>
<xs:element name="Replace">
<xs:complexType>
<xs:attribute name="old" type="AnythingButLowerCase" use="required" />
<xs:attribute name="new" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:simpleType name="AnythingButLowerCase">
<xs:restriction base="xs:string">
<xs:pattern value="[^a-z]+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
<Replace old="A1020____9" new="A1020"/>
<Replace old="a1020____9" new="A1020"/>
</Replacements>
Now this serves as what I want it to.

Apache CXF 2.2.7 Spring 3 Web Service Unmarshalling Error: unexpected element

I have developed a simple web service application using Apache CXF 2.2.7 and Spring 3, deployed onto Tomcat as a WAR file, but I'm getting the following error message:
12-Apr-2010 15:56:12 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
WARNING: Interceptor for {http://services.aristabi.com/}ReportingServiceImplService#{http://services.aristabi.com/}getNewBusinessVolumeByCreateDate_v2 has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"http://services.aristabi.com/", local:"searchCriteria"). Expected elements are <{}searchCriteria>
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:764)
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:623)
at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:128)
at org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:106)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:109)
at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:98)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:406)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:178)
at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:142)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.xml.bind.UnmarshalException
- with linked exception:
[javax.xml.bind.UnmarshalException: unexpected element (uri:"http://services.aristabi.com/", local:"searchCriteria"). Expected elements are <{}searchCriteria>]
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:425)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:362)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:339)
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:749)
... 25 more
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://services.aristabi.com/", local:"searchCriteria"). Expected elements are <{}searchCriteria>
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:254)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:249)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:116)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.childElement(Loader.java:101)
at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.childElement(StructureLoader.java:245)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:478)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:459)
at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:242)
at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:176)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:360)
... 27 more
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://services.aristabi.com/", local:"searchCriteria"). Expected elements are <{}searchCriteria>
... 38 more
This is probably a simple issue, but I can't seem to be able to resolve it. Can anyone point me in the right direction to solve this issue?
Thanks,
Zahanghir
Btw, this is what my wsdl looks like
<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions name="ReportingServiceImplService" targetNamespace="http://services.aristabi.com/" xmlns:ns1="http://cxf.apache.org/bindings/xformat" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://services.aristabi.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://services.aristabi.com/" xmlns:tns="http://services.aristabi.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="getNewBusinessVolumeByCreateDate" type="tns:getNewBusinessVolumeByCreateDate" />
<xs:element name="getNewBusinessVolumeByCreateDateResponse" type="tns:getNewBusinessVolumeByCreateDateResponse" />
<xs:element name="getNewBusinessVolumeByCreateDate_v2" type="tns:getNewBusinessVolumeByCreateDate_v2" />
<xs:element name="getNewBusinessVolumeByCreateDate_v2Response" type="tns:getNewBusinessVolumeByCreateDate_v2Response" />
<xs:element name="newBusinessLead" type="tns:newBusinessLead" />
<xs:element name="quotes" type="tns:quotes" />
<xs:element name="searchCriteria" type="tns:searchCriteria" />
<xs:complexType name="getNewBusinessVolumeByCreateDate">
<xs:sequence>
<xs:element minOccurs="0" name="agent" type="xs:string" />
<xs:element minOccurs="0" name="broker" type="xs:string" />
<xs:element minOccurs="0" name="businessUnit" type="xs:string" />
<xs:element minOccurs="0" name="fromMonth" type="xs:string" />
<xs:element minOccurs="0" name="fromYear" type="xs:string" />
<xs:element minOccurs="0" name="region" type="xs:string" />
<xs:element minOccurs="0" name="toMonth" type="xs:string" />
<xs:element minOccurs="0" name="toYear" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="getNewBusinessVolumeByCreateDateResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="tns:newBusinessLead" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="newBusinessLead">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="convertedQuotes" nillable="true" type="tns:quotes" />
<xs:element maxOccurs="unbounded" minOccurs="0" name="declinedQuotes" nillable="true" type="tns:quotes" />
<xs:element maxOccurs="unbounded" minOccurs="0" name="ntuQuotes" nillable="true" type="tns:quotes" />
<xs:element maxOccurs="unbounded" minOccurs="0" name="pendingQuotes" nillable="true" type="tns:quotes" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="quotes">
<xs:sequence>
<xs:element minOccurs="0" name="month" type="xs:string" />
<xs:element name="premium" type="xs:int" />
<xs:element minOccurs="0" name="quoteStatus" type="xs:string" />
<xs:element name="volume" type="xs:int" />
<xs:element minOccurs="0" name="year" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="arrayList">
<xs:complexContent>
<xs:extension base="tns:abstractList">
<xs:sequence />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType abstract="true" name="abstractList">
<xs:complexContent>
<xs:extension base="tns:abstractCollection">
<xs:sequence />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType abstract="true" name="abstractCollection">
<xs:sequence />
</xs:complexType>
<xs:complexType name="getNewBusinessVolumeByCreateDate_v2">
<xs:sequence>
<xs:element minOccurs="0" name="searchCriteria" type="tns:searchCriteria" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="searchCriteria">
<xs:sequence>
<xs:element minOccurs="0" name="agent" type="xs:string" />
<xs:element minOccurs="0" name="broker" type="xs:string" />
<xs:element minOccurs="0" name="businessUnit" type="xs:string" />
<xs:element minOccurs="0" name="fromMonth" type="xs:string" />
<xs:element minOccurs="0" name="fromYear" type="xs:string" />
<xs:element minOccurs="0" name="region" type="xs:string" />
<xs:element minOccurs="0" name="toMonth" type="xs:string" />
<xs:element minOccurs="0" name="toYear" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="getNewBusinessVolumeByCreateDate_v2Response">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="tns:newBusinessLead" />
</xs:sequence>
</xs:complexType>
<xs:element name="InvalidUserCredentialsException" type="tns:InvalidUserCredentialsException" />
<xs:complexType name="InvalidUserCredentialsException">
<xs:sequence />
</xs:complexType>
<xs:element name="tokenString" nillable="true" type="xs:string" />
</xs:schema>
</wsdl:types>
<wsdl:message name="InvalidUserCredentialsException">
<wsdl:part element="tns:InvalidUserCredentialsException" name="InvalidUserCredentialsException">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getNewBusinessVolumeByCreateDateResponse">
<wsdl:part element="tns:getNewBusinessVolumeByCreateDateResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getNewBusinessVolumeByCreateDate">
<wsdl:part element="tns:getNewBusinessVolumeByCreateDate" name="parameters">
</wsdl:part>
<wsdl:part element="tns:tokenString" name="tokenString">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getNewBusinessVolumeByCreateDate_v2Response">
<wsdl:part element="tns:getNewBusinessVolumeByCreateDate_v2Response" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getNewBusinessVolumeByCreateDate_v2">
<wsdl:part element="tns:getNewBusinessVolumeByCreateDate_v2" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="IReportingService">
<wsdl:operation name="getNewBusinessVolumeByCreateDate">
<wsdl:input message="tns:getNewBusinessVolumeByCreateDate" name="getNewBusinessVolumeByCreateDate">
</wsdl:input>
<wsdl:output message="tns:getNewBusinessVolumeByCreateDateResponse" name="getNewBusinessVolumeByCreateDateResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getNewBusinessVolumeByCreateDate_v2">
<wsdl:input message="tns:getNewBusinessVolumeByCreateDate_v2" name="getNewBusinessVolumeByCreateDate_v2">
</wsdl:input>
<wsdl:output message="tns:getNewBusinessVolumeByCreateDate_v2Response" name="getNewBusinessVolumeByCreateDate_v2Response">
</wsdl:output>
<wsdl:fault message="tns:InvalidUserCredentialsException" name="InvalidUserCredentialsException">
</wsdl:fault>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ReportingServiceImplServiceSoapBinding" type="tns:IReportingService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="getNewBusinessVolumeByCreateDate">
<soap:operation soapAction="" style="document" />
<wsdl:input name="getNewBusinessVolumeByCreateDate">
<soap:header message="tns:getNewBusinessVolumeByCreateDate" part="tokenString" use="literal">
</soap:header>
<soap:body parts="parameters" use="literal" />
</wsdl:input>
<wsdl:output name="getNewBusinessVolumeByCreateDateResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getNewBusinessVolumeByCreateDate_v2">
<soap:operation soapAction="" style="document" />
<wsdl:input name="getNewBusinessVolumeByCreateDate_v2">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="getNewBusinessVolumeByCreateDate_v2Response">
<soap:body use="literal" />
</wsdl:output>
<wsdl:fault name="InvalidUserCredentialsException">
<soap:fault name="InvalidUserCredentialsException" use="literal" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ReportingServiceImplService">
<wsdl:port binding="tns:ReportingServiceImplServiceSoapBinding" name="ReportingServiceImplPort">
<soap:address location="http://localhost:8889/AristaInsuranceServices/reportingService" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I don't have a XSD. Can you please point out what is wrong with the WSDL?
I know this question is a year old with no accepted answer but I had exactly the same error today.
Like the original question poster, I have a Java-First service with a method that returns an object. The problem for me was that I added an extra property to the bean that gets returned by the service method.
Once I republished/redeployed the service, the client side jaxb generated class for the return object was no longer the same as the server side WSDL complex-type (i.e. the client side classes lacked the new property) and so I had the "unexpected element" exception with the name of the missing property.
Once I regenated all the jaxb objects using WsdlToJava the client side code worked as normal.
I also came across a suggested workaround for this situation where you might not want to regenerate your client code every time a property changes on the server side. The solution is basically to ignore the unexpected element exception on the client side because it is for new elements that your existing code doesn't use. Link here to the solution:
http://whileonefork.blogspot.com/2010/11/cxf-backwards-compatibility-adding.html
The incoming message is invalid. Basically, it doesn't match the schema. (or at least what JAXB is expecting) Basically, someplace in the message, you have an element like:
<ns1:searchCriteria> ..... </ns1:searchCriteria>
or possibly with no namespace prefix, but with a default namespace set someplace. However, JAXB is expecting the element to be unqualified. something like:
<searchCriteria> ..... </searchCriteria>
Definitely check the sending side to see what they are sending as well as check the schema to see what the schema says it should look like. (elementFormDefault=unqualified is the default if not specified)
I had a similar problem, but the reason was the whitespace in the element name in the xsd schema.
elemname__. I just corrected it to elemname and now it works. The Error was thrown because xml had elemname not elemname__.

Resources