In the process of moving to Spring WS and using JAXB from wsdl to generate the objects used in the Soap message. I am having an issue trying to get the Custom Exception into the details field of the Soap Fault message. The following is how the existing fault message is returned (FooException embedded in detail).
<env:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header/>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>Service specific exception: com.test.FooException: Invalid authentication credentials. Please try again.</faultstring>
<detail>
<n1:FooException xsi:type="n1:FooException" xmlns:n1="java:com.test">
<errorCode xsi:type="xsd:int">101</errorCode>
<errorReason xsi:type="xsd:string">InvalidUserCredentials:Invalid authentication credentials. Please try again</errorReason>
</n1:FooException>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
I have setup a customer exceptionResolver bean identifier in the spring config xml file.
<bean id="exceptionResolver" class="com.test.FacadeExceptionHandler">
<property name="order" value="1"></property>
<property name="defaultFault" value="SERVER"/>
<property name="exceptionMappings">
<value> com.test.FooException=SERVER,FaultMsg </value>
</property>
</bean>
I created the FacadeExceptionHandler and it is getting called, but I cannot figure out how to get the FooException into the details portion of the fault message.
Any help would be appreciated!!!
Thanks in advance for your help!
I think you almost get it all, in your FacadeExceptionHandler you must override the customizeFault method (doc) and then add the detail for the fault (you have your Exception as a parameter there).
All this custom detail handling for Soap Fault messages is explained in detail in this entry: http://www.stevideter.com/2009/02/18/of-exceptionresolvers-and-xmlbeans/
You cannot return to SOAP client fault with such depth of nested elements in <detail> element cause in Spring WS SoapFault has list of SoapFaultDetail which has list of SoapFaultDetailElement but SoapFaultDetailElement is just detail message in String. So in Spring WS max depth of SOAP Fault details is one.
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Сообщение не соответствуют схеме сервиса СМЭВ.</faultstring>
<detail>
<InvalidContent xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1">cvc-complex-type.2.4.a: Invalid content was found starting with element 'ns:SenderProvidedRequestData1'. One of '{"urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1":SenderProvidedRequestData}' is expected.</InvalidContent>
<InvalidContent xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1">cvc-complex-type.2.3: Element 'ns:CallerInformationSystemSignature' cannot have character [children], because the type's content type is element-only.</InvalidContent>
<InvalidContent xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1">cvc-complex-type.2.4.b: The content of element 'ns:CallerInformationSystemSignature' is not complete. One of '{WC["http://www.w3.org/2000/09/xmldsig#"]}' is expected.</InvalidContent>
</detail>
</SOAP-ENV:Fault>
Related
When generating a response, LightSAML IDP samples show it generates Attributes as mapping rules in the URL format:
<AttributeStatement>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
<AttributeValue>email#example.com</AttributeValue>
</Attribute>
</AttributeStatement>
Is there a way to tell LightSAML to generate Attributes as constructs in the generic format, like SimpleSAMLPHP does:
<saml:AttributeStatement>
<saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xsi:type="xs:string">email#example.com</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
Apologies if I am using the incorrect terminology in my above question. Still learning SAML.
My Mulesoft process is making a call to SuccessFactors API. The /LOGIN call results in a response like this.
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<loginResponse xmlns="urn:sfobject.sfapi.successfactors.com" xmlns:ns2="urn:fault.sfapi.successfactors.com">
<result>
<sessionId>9A95*******A2631B8E820894CA.ps8bsfapi52t</sessionId>
<msUntilPwdExpiration>9223372036854775807</msUntilPwdExpiration>
</result>
</loginResponse>
</S:Body>
</S:Envelope>
I've the following name spaces declared in my namespace manager
<mulexml:namespace-manager>
<mulexml:namespace prefix="S" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
<mulexml:namespace prefix="ns2" uri="urn:fault.sfapi.successfactors.com"/>
<mulexml:namespace prefix="" uri="urn:sfobject.sfapi.successfactors.com"/>
</mulexml:namespace-manager>
I want to read the sessionId into a mule session variable.
<set-session-variable variableName="SESSION" value="#[xpath('//S:Envelope/S:Body/loginResponse/result/sessionId').text]" doc:name="Get Session from Login"/>
But, upon execution I end up in this
<faultstring>Execution of the expression "xpath('//S:Envelope/S:Body/loginResponse/result/sessionId').text" failed. (org.mule.api.expression.ExpressionRuntimeException).</faultstring>
The XPath checks out well on any other tool but for Mulesoft.
Use XPATH with * as namespace, so you dont need to bother about namespace.
#[xpath('//*:Envelope/*:Body/*:loginResponse/*:result/*:sessionId').text]
xpath is deprecated new version of mule.
Update:
#[xpath3('//*:Envelope/*:Body/*:loginResponse/*:result/*:sessionId')]
Hope this helps.
Seems to be a simple task but I cannot get my head around it.
I have a Spring integration chain which calls an external Webservice, which returns an XML. I would like to use that XML response in a downstream XpathRouter.
What expected-response-type should I use?
<int:chain input-channel="filesChannel">
<!-- ... some previous components in the chain -->
<int-http:outbound-gateway
http-method="POST"
url="http://web/service/url"
expected-response-type="java.lang.String" />
<int-xml:xpath-router default-output-channel="resultChannel">
<int-xml:xpath-expression expression="/order/status" />
<int-xml:mapping value="Error" channel="importErrorChannel" />
</int-xml:xpath-router>
</int:chain>
It doesn't seem like the xpath-router can consume the XML returned by the webservice. When I debug the router with a breakpoint on the following line:
Node node = this.converter.convertToNode(message.getPayload());
The node is null, although the message does contain valid XML.
Is it because I am not setting the right expected-response-type?
Here is the response XML I receive from the service:
<apiResponse version="1.0">
<orders>
<order>
<orderReference>test_2_3045342</orderReference>
<status>Error</status>
<errors>
<error>
<errorCode>1100</errorCode>
<errorMessage><![CDATA[ "Field is required: dropWindow" ]]></errorMessage>
</error>
</errors>
</order>
</orders>
</apiResponse>
Ok, I found my mistake - it was actually in the XPATH expression. It should have been //order/status to enable deep search.
The java.lang.String expected-response-type works just fine with XML XpathRouter.
Thanks
In my application I have to consume a service provided by a third party application. The response they provide is always 200 and they change the body based on whether data is available or not or error occurred, as given below
If data is there then
<products>
<product></product>
<product></product>
</products>
If data is empty then
<message> No record found </message>
If some validation failed then
<error>Invalid Id</error>
I am using RestTemplate.exchange to consume the service, my question is if there only single type of root element then we pass the respective class as ParameterizedTypeReference but here how to map the response and unmarshall it.
Use jaxb or jackson to unmarshall the xml.
The right thing to do here is to ask the third party to change their service response to have a root tag. The response object would then look something like this:
<response>
<products>
<product></product>
<product></product>
</products>
<message> No record found </message>
<error>Invalid Id</error>
</response>
With this, you will only need to be concerned about response object and you can check the presence of respective sub-tags.
Other option to make this work for you is to do the exchange by passing String.class as the type reference. Then you would need to do the check in your code to see if the string response returned is products or message or error
I'm trying to use Spring's RestTemplate to get a response from an atom source. Is there a way to easily pull values from the response or deserialize it?
The response:
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:apps='http://schemas.google.com/apps/2006'>
<id>https://apps-apis.google.com/a/feeds/domain/2.0/blah/verification/mx</id>
<updated>2013-03-19T19:47:02.805Z</updated>
<apps:property name='verified' value='false'/>
</entry>
Parse the feed with Abdera or ROME. They have nice representations of Atom feeds and feed entries with all their composing types.