How to convert SOAP response with xsi values to json in WSO2esb - json

I'm using wso2 esb 4.8.1 version for SOAP to rest conversion with as API. I have a soap request with xsi values. After I generate the proper soap request with script mediator and um getting an expected response. But I have an issue with response. Because I need t convert the soap response into json. When I tried with following out sequence um not getting the proper json response with axis2. How can I convert this soap response into json properly?
This it the soap response.
<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>
<ns1:easyDownloadResponse xmlns:ns1="http://usermanage.ivas.huawei.com" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<easyDownloadReturn href="#id0"/>
</ns1:easyDownloadResponse>
<multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://response.usermanage.ivas.huawei.com" id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:EasyDownloadResp">
<eventClassName xsi:type="xsd:string" xsi:nil="true"/>
<failedResources xsi:type="soapenc:Array" xsi:nil="true"/>
<operationID xsi:type="xsd:long">0</operationID>
<resultCode xsi:type="xsd:int">0</resultCode>
<resultInfo xsi:type="xsd:string" xsi:nil="true"/>
<returnCode xsi:type="xsd:string">000000</returnCode>
<toneTransactionID xsi:type="soapenc:Array" xsi:nil="true"/>
<transactionID xsi:type="xsd:string" xsi:nil="true"/>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
This is the response which i'm getting
{"easyDownloadResponse":{"#encodingStyle":"http://schemas.xmlsoap.org/soap/encoding/","easyDownloadReturn":{"#href":"#id0"}}}
This is my out sequence
<outSequence xmlns="http://ws.apache.org/ns/synapse">
<property name="messageType" value="application/json" scope="axis2" type="STRING"></property>
<send></send>
</outSequence>
All your answers are highly welcome.

Finally I found the solution for the issue. In the normal case we use
<property name="messageType" value="application/json" scope="axis2" type="STRING"></property>
But this axis2 property cannot convert the complex soap response into json such as with xsi.
For that need to use the following axis2 property. Then it converts the entire soap response into Json as we expected.
<property name="messageType" value="application/json/badgerfish" scope="axis2" type="STRING"></property>
This is my full outsequence.
<outSequence xmlns="http://ws.apache.org/ns/synapse">
<property name="messageType" value="application/json/badgerfish" scope="axis2" type="STRING"></property>
<send></send>
</outSequence>

You can try payload mediator to get exact json format 1. But still you may have to uncomment the following lines in
$ESB_HOME/repository/conf/axis2/axis2.xml
<!--messageFormatter contentType="application/json"
class="org.apache.axis2.json.JSONStreamFormatter"/-->
<!--messageBuilder contentType="application/json"
class="org.apache.axis2.json.JSONStreamBuilder"/-->
By default, JSON messages are converted to XML when they are received by the PayloadFactor mediator. However, if you enable the JSON stream formatter and builder, incoming JSON messages are left in JSON format.
And also you can use script mediator again (In outsequence) to modify your json response. Refer this sample

Related

filtering json fileds without conditions using wso2 esb

In WSO2 ESB,how to pass certain json fields as request?
And adding the remaining json fields with the response?
You need to use API's if you want to pass json as the request, you can frame json request and test via SOAP UI by selecting the media type as application/json.
ESB will accept this request and then by default converts it into an XML format, you can use xpath to perform different instructions and then if you want json as the output of your API you need to use the below syntax before exiting your API.<property name="messageType" scope="axis2" type="STRING" value="application/json; charset=utf-8"/>
<property name="ContentType" scope="axis2" type="STRING" value="application/json; charset=utf-8"/>

JSON to SOAP WSO2 Api manager xml sequence

I would to publish a SOAP service as REST(json) API . The service operation I want to expose has a xml sequence element in the WSDL/XSD definition:
<xs:complexType name="hellolist">
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="hellolistResponse">
<xs:sequence>
<xs:element name="return" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
I don't know how to map a JSON array to a xml sequence using PayloadFactory. All the samples I found deal only with simple json and SOAP messages like this sample WSO2 transformation.
I would like to transform this json message:
{"hellolist":{"name":["Peter","Mary","Ann","James"]}}
To this soap message:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:dum="http://dummyservice2.com/">
<soapenv:Header/>
<soapenv:Body>
<dum:hellolist>
<name>Peter</name>
<name>Mary</name>
<name>Ann</name>
<name>James</name>
</dum:hellolist>
</soapenv:Body>
</soapenv:Envelope>
You can use payload factory mediator to do this. It can be used to transform or replace message content in between the client and the back-end server. In the case of your scenario you can configure a proxy service as below.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="json_to_xml_factory"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<payloadFactory media-type="xml">
<format>
<dum:hellolist xmlns:dum="http://dummyservice2.com/">
<name xmlns="">$1</name>
<name xmlns="">$2</name>
<name xmlns="">$3</name>
<name xmlns="">$4</name>
</dum:hellolist>
</format>
<args>
<arg evaluator="json" expression="$.hellolist.name[0]"/>
<arg evaluator="json" expression="$.hellolist.name[1]"/>
<arg evaluator="json" expression="$.hellolist.name[2]"/>
<arg evaluator="json" expression="$.hellolist.name[3]"/>
</args>
</payloadFactory>
<log level="full"/>
</inSequence>
<outSequence/>
</target>
<description/>
</proxy>
Please refer below links for more information on this.
https://docs.wso2.com/display/ESB490/PayloadFactory+Mediator
http://christinetechtips.blogspot.com/2014/02/payload-factory-mediators-to-work-with.html
http://madhukaudantha.blogspot.com/2013/05/wso2-esb-payload-mediator-tutorial.html
If you have a non-static payload (your case), payload-factory-mediator will not be the solution (only for static payload). The best way for your kind of a problem is using xslt mediator + enrich mediator in WSO2 ESB. You can try out this example, https://docs.wso2.com/display/ESB481/Sample+440%3A+Converting+JSON+to+XML+Using+XSLT
Or you can use script mediator in case, as explained in this example.https://docs.wso2.com/display/ESB481/Sample+350%3A+Introduction+to+the+Script+Mediator+Using+JavaScript . Yet not the most preffered way.
I have done your kind of conversions using WSO2 ESB as I described above. But I don't know whether those mediator tools are also available with WSO2 APIM (I couldn't find any example when I googled for your problem).
Try the steps mention below
Steps to Convert a SOAP Test service in SoapUI with assertions into JSON service with assertions
Copy the project xml file of SOAP UI project
Open the copied xml file
Find the format for all assertion types in JSON that is equal in SOAP call assertion
Now convert all the soap assertions in the config node of the test step node to JSON assertion config node format as found in the previous step
Convert the SOAP call request into JSON call by changing all the fields as below
• Add the output_format node
• Add the Rest call – service name
• Remove the nodes without value and convert the others into JSON format like {“node name” : “value”} etc.,
In the test step node type attribute – it will be “request” change it to “httprequest”
Save the file and open it in SOAP UI
Now you can see all the services in the newly opened project will be in JSON format and all assertions will be available that were in SOAP call previously.
also refer the link which helps to convert the request completely including the assertions
please reply if it is not helpful

411 Response on Post from WSO2 API Manager to REST endpoint

I have setup a REST endpoint in WSO2 AM that calls out to another REST endpoint. When the call is made I am receiving a 411 response code. The request contains a JSON body, the content type and accepts header are set to application/json. I can curl the backing service that WSO2 is accessing directly with the same params and it works correctly. It seems that WSO2 AM is stripping or not sending the content-length.
Why is the content length not being sent to the REST endpoint that is being accessed?
Sending content-length is disabled by default because it can cause performance degradation. But you can enable it by adding following to the api's insequence. (see https://docs.wso2.com/display/AM1100/Adding+Mediation+Extensions on adding custom sequence to an api)
<property name="COPY_CONTENT_LENGTH_FROM_INCOMING" value="true" scope="axis2"/>
<property name="FORCE_HTTP_CONTENT_LENGTH" scope="axis2" value="true"></property>
following is a sample sequnce
<sequence xmlns="http://ws.apache.org/ns/synapse" name="contentLengthadd">
<property name="COPY_CONTENT_LENGTH_FROM_INCOMING" value="true" scope="axis2"/>
<property name="FORCE_HTTP_CONTENT_LENGTH" scope="axis2" value="true"></property>
</sequence>
This sequence will get the content length from incoming request request and pass it the request header to the backend.
you can read more about these two properties in https://docs.wso2.com/display/ESB481/HTTP+Transport+Properties#HTTPTransportProperties-FORCE_HTTP_CONTENT_LENGTH

Spring RESTful Web Service with JSON gives HTTP 406 error code

I am using Spring 3.2.5 to create a RESTful web service. To implement it I've used #ResponseBody tag. When I use InternalResourceViewResolver and try to load Html response then it is working fine. But when I call a URL which is marked as #ResponseBody then it gives HTTP 406 error code with error text as
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
I have included Jackson jar files in my lib directory as well.
Here is my controller method which handles service request.
#ResponseBody
#RequestMapping (value = "/resp.htm")
public Data jsonResp() {
Data d = new Data();
d.setName("TEst");
d.setAddr("Address....");
return d;
}
There are lots of questions have been asked & answered, I've tried many of them, but it still gives the same result. Then I came across a new kind of answer, which was stating to use ContentNegotiatingViewResolver. By using it I am able to view response in intended format. That is JSON format.
After using ContentNegotiatingViewResolver, servlet dispatcher code looks like this:
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
</map>
</property>
<property name="defaultViews">
<list>
<!-- JSON View -->
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2" />
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
So, my question is, whenever we require to use Spring's Web Service feature, do we must require to have ContentNegotiatingViewResolver?
Add gson in your class path. as well as jackson
I had a similar issue while calling a spring rest service from angular 8 for uploading a file. I was using ResponseEntity to encapsulate the success or failure message for which I was having the 406 response. all I did was in the UI side this.httpClient.post(url, formData,{responseType: 'text'}) and I was able accept the string as response from the service response.
The annotation #ResponseBody used with custom class types, generally uses MappingJackson2HttpMessageConverter to convert the object to JSON and return it in application/json content.
Since your request doesn't contain an Accept header for application/json, Spring deems the content it's creating as unacceptable and instead returns a 406.
You could simply change your request to add the Accept header. (You can't do this easily in a browser).
In my case the request had .html suffix and received this error. Once removed, it worked fine.
All you need to do is to add jackson libraries to your classpath find them Here

How to convert the JSON in WSO2 ESB

I am trying to pass my JSON as a object to a WSO2 ESB.
I am getting JSON like this:
'{FIELDNAME":"NAME",FIELDVALUE:"KISHORE"}'
This JSON I need to pass my ESB as a dynamic column. But Its accepting like JSON {"NAME":"KISHORE"}. How can I convert from above JSON to below one in WSO2 ESB. If I get above one I am unable to pass to proxy. If I get below one I will pass like this (//name/child::text()) then I will get value as "KISHORE" I was tried with ENRICH mediator but its not working.
<proxy xmlns="http://ws.apache.org/ns/synapse" name="test_dynamic" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<enrich>
<source type="body" clone="true"/>
<target type="property" property="RM"/>
</enrich>
<property name="RM" expression="//fieldname/child::text()" scope="default" type="STRING"/>
<log level="custom">
<property name="r_no" expression="get-property('R_no')"/>
<property name="r_value" expression="get-property('R_value')"/>
<property name="emp_d" expression="get-property('emp')"/>
<property name="RM" expression="get-property('RM')"/>
</log>
<log level="full"/>
</inSequence>
</target>
<description></description>
</proxy>
ANS: request, Envelope:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body><fieldname>e_no</fieldname><fieldvalue>5</fieldvalue></soapenv:Body>
</soapenv:Envelope>
I think you should send the JSON message like this:
'{"RECORD":{FIELDNAME":"NAME",FIELDVALUE:"KISHORE"}}'
then get the value by the "Property" mediator in WSO2 ESB, like
<property name="FIELDNAME" expression="//FIELDNAME/text()" scope="default" type="STRING"/>
<property name="FIELDVALUE" expression="//FIELDVALUE/text()" scope="default" type="STRING"/>
The link provided below by WSO2 explains the exact usecase which you are interested in solving
Steps:
Convert JSON to XML using the XSLT mediator
Use the Enrich mediator to replace the Body of the SOAP message
Follow this link for detailed info and actual proxy configuration
https://docs.wso2.com/display/ESB480/Sample+440%3A+Converting+JSON+to+XML+Using+XSLT