Hi,
Recently, I had a requirement where I was supposed to send a request to the web-service in “x-www-form-urlencoded” format using POST Method via REST Adapter. I had come across various scn links on how to handle such scenarios such as (https://archive.sap.com/discussions/thread/3823412 and https://answers.sap.com/questions/335020/rest-receiver-adapter-how-to-do-post-using-x-www-f.html ) but I couldn’t find the blog with complete configuration of REST Adapter. I hope this blog will help PI consultants, if they have similar kind of requirement.
Detailed Requirement:
Request Method: POST
URL : http://<host>:<port>/abc/abc.aspx?transid=174178189819&Action=GetDenominationCategory&BrowsePlanCategory=1&OperatorAlias=AIRC&RegionAlias=WB
Content-type : application/x-www-form-urlencoded
Request Body:
transid=174178189819
BrowsePlanCategory=1 will change as per requirement.
OperatorAlias=AIRC will change as per requirement.
RegionAlias=WB will change as per requirement.
Note: URL Parameter values are dynamic. These values are coming from source payload.
Response Structure:
Content-type= application/json
{“BrowsePlanCategory”:null,”Operator”:null,”Region”:null,”DenominationCategory”:”[{“CategoryId”:1,”CategoryName”:”A Plan”},{“CategoryId”:2,”CategoryName”:”B Plan”}]”,”Plans”:null}
This is how I have implemented it in PI:
ESR Objects:
Data Types:
Define a data type that includes the required parameters for your REST call.
Define another data type that includes all the required parameters from the REST.
Request Mapping with UDF:
All the parameters are mapped one to one but in our requirement, URL is dynamic. so we need to write a UDF to pass these values dynamically and we can access using ASMA. We also need to write a Java mapping/XSLT mapping to send the request in a single string as our Request type is “x-www-form-urlencoded” which basically means raw data.
Note: If the URL is static then we don’t need message mapping we can directly send the request in String format using java mapping only.
UDF to dynamically set REST URL parameters:
public String DynamicHeader(String var1, String var2, String var3, String var4, String var5, Container container) throws StreamTransformationException{
DynamicConfiguration conf = (DynamicConfiguration) container.getTransformationParameters().get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);
DynamicConfigurationKey key1 = DynamicConfigurationKey.create("http://sap.com/xi/XI/System/REST","XHeaderName1");
conf.put(key1, var1);
DynamicConfigurationKey key2 = DynamicConfigurationKey.create("http://sap.com/xi/XI/System/REST","XHeaderName2");
conf.put(key2, var2);
DynamicConfigurationKey key3 = DynamicConfigurationKey.create("http://sap.com/xi/XI/System/REST","XHeaderName3");
conf.put(key3, var3);
DynamicConfigurationKey key4 = DynamicConfigurationKey.create("http://sap.com/xi/XI/System/REST","XHeaderName4");
conf.put(key4, var4);
DynamicConfigurationKey key5 = DynamicConfigurationKey.create("http://sap.com/xi/XI/System/REST","XHeaderName5");
conf.put(key5, var5);
return "";
}
Java Mapping code to send the request in String Format:
package com.pi.browseplan;
import org.json.*; // import jar file attached in the blog
import com.sap.aii.mapping.api.*;
import java.io.*;
import java.util.Map;
public class ParseXMLStructure extends AbstractTransformation {
public void transform(TransformationInput in, TransformationOutput out) throws StreamTransformationException {
try {
InputStream inputstream = in.getInputPayload().getInputStream(); String sourcexml = ""; String targetxml =""; String line="";
BufferedReader br = new BufferedReader( new InputStreamReader(inputstream));
while ((line = br.readLine()) != null)
sourcexml +=line+"\n";
br.close();
// convert the xml Structure to JSON
JSONObject xmlJSONObj = XML.toJSONObject(sourcexml);
String jsonstring = xmlJSONObj.toString(0);
//formatting to convert string in required structure
//Required structure:transid=d&Action=d&BrowsePlanCategory=d&OperatorAlias=dd&RegionAlias=d
jsonstring =jsonstring.replaceAll("\\{", "").replaceAll("\\}","");
jsonstring=jsonstring.replace("\"", "");
jsonstring=jsonstring.replace(":", "=");
jsonstring=jsonstring.replace(",","&");
//If you are getting the response in correct format .you may need to do some changes here as per your //structure.
for(int i=0;i<jsonstring.length();i++)
{
char value=jsonstring.charAt(i);
if(value == '&')
{
jsonstring = jsonstring.substring(i+1,jsonstring.length());
break;
}
}
targetxml=jsonstring.trim();
out.getOutputPayload().getOutputStream().write(targetxml.getBytes());
}
catch (Exception exception) {
getTrace().addDebugMessage(exception.getMessage());
throw new StreamTransformationException(exception.toString());
}
}
}
Response Mapping
One -to- one mapping for response.
Operation Mapping:
Output after applying message mapping and Java Mapping in Operation Mapping:
Generally, we don’t need UDF to pass parameters dynamically in case of REST Adapter. As REST Adapter already have this feature to set parameters through XPATH Expression.
But in our case the response from Operation Mapping is not xml so in this case XPATH Expression will not work. That’s why we need to use UDF to set parameters dynamically in REST Adapter and access those parameters using ASMA.
ID Objects:
REST Receiver configuration:
Create a REST receiver channel with your target URL and request parameters as required by your call. Channel sets the Values of request parameters from UDF.
Note: In case of static URL, you don’t need to set Pattern variable Replacement. You just need to enter URL Pattern.
Likewise set the values of all request parameters.
Set the Operation mode to POST.
Set Request Format as JSON as of now, we will set it via Adapter Module. Set the Response Format as per your requirement.
Use Message Transformation Bean to convert the Request format to “x-www-url-encoded”.
Snapshots:
Dynamic configuration :
Please find attached updated jar file for json to xml conversion. As the standard json jar file doesn’t create xml structure in sequence. Import this jar while writing Java Mapping.
https://drive.google.com/open?id=1qCVAuBYAlLNMFQUsCagqEGaUMcbtrReC
I hope this blog is helpful for you.
Hi Sonam,
Great keep it up, keep updating
Regards
Ahamad Shaik
Hello Sonam,
Great blog, thanks for sharing.
One question: why use ASMA & UDF to set URL Variables instead of using JSON Expressions?
Regards,
JN
HI Jose,
Here the Request Format is in raw string(x-www-form-urlencoded) not in JSON /XML Structure, so the JSON EXPRESSION/XPATH EXPRESSION will not work in this case. So we will have to use ASMA.
Awesome Blog, I wish this blog was available when I was struggling with x-www-form-urlencoded…. Almost same requirement… M sure this will be good guide for others….
BR,
Rashmi
Hello
Your thoughts on this please.
https://answers.sap.com/questions/12879150/how-to-send-http-body-parameters-in-sap-po-75.html
Excellent Blog.
Regards,
Pradeep Kumar
Hi Sonam,
Its an excellent.
I manage to post request using your blog but not able to capture response which is also in a URL encoded format.
can you please help me with this.
Regards,
Akshay Ruia
Hi Akash,
I think for response you will need java mapping to convert the Response string into a XML Structure. you can refer the same java mapping but with some modifications, like you will have to first convert your Response string to JSON Structure and then you can convert JSON Structure to XML.
Thanks,
Sonam Ramsinghani
Hi Sonam Ramsinghani,
Thanks & Regards,
Dilip
Hi Sonam Ramsinghani , may I ask, why you used MessageTransformBean to set the “Content-Type” header to “application/x-www-url-encoded” and why you didn’t used the “HTTP-Header”-tab in the REST-Adapter itself?
Hi Raffael, I tried using HTTP Tab initially but it didn’t work for me. Later i did many changes and used MTB then i didn’t try HTTP Tab. you can try it and let us know the result.:)
Hi Sonam,
atleast for me the HTTP header tab worked out today. 🙂
Great. Thanks for informing.:)
Your thoughts on this please.
https://answers.sap.com/questions/12879150/how-to-send-http-body-parameters-in-sap-po-75.html
Thanks!
Hi Experts,
We are also facing the same dilemma.
We have to send messages from postman to rest sender channel in x-www-form-urlencoded format.
Is there is specific setting we have to mention in the sender channel to receive the data correctly in PI.Right now we are facing the below issue.
BR
Karan
Hello Sonam,
cant find the attached Jar, can you please share a link, so that I can download it from there.
Regards,
Sushant
Hi Sonam
Thanks for very helpful blog.
It works for me till I get “&” in value of one of the fields.
e.g. if companyname is “S & S traders” the resulting string of mapping becomes becomes : company=S & S tranders&state=Victoria
Because of ampersand in field company name as well as separator, the receiving party is facing issues.
Is special conversion required for special chars like ampersand?
Thanks again
Sunit
Hi Sonam Ramsinghani,
Thanks for the blog 🙂
I have same scenario in my project and I am following this blog.
While doing mapping test in ESR I am getting the below error.
This seems like JSON jar file is missing in PI server.
Do I need to ask my Basis team to place the jar file?
Did you place JSON jar files in your PI server?
Did you face this error? If yes, how did you resolve?
Thanks in advance.
Regards,
Pavan
Yes you need to import json jar file in imported archives. You can either download standard json jar or you can use the updated one for which I have already shared the link.
Hi Sonam Ramsinghani ,
Thanks for the response 🙂
I have imported the json jar file in imported archives and it worked 🙂
Message has been posted. But I am not able to see the response message which in application/json format.
Do we need to do anything apart from this to get response message or did I miss anything REST adapter for response structure? 🙁
Regards,
Pavan
Hi Pavan,
There is no extra configuration required apart from the one given in the blog.
Sonam Ramsinghani
Your thoughts on this please.
https://answers.sap.com/questions/12879150/how-to-send-http-body-parameters-in-sap-po-75.html
Thanks!
Hi Experts,
I am working with REST synchronous scenario my rest response as shown below. I am able get one Item. I am note able get all items Can you please guide how can get Items. Thanks in advance for your help.
Hi! Can someone help me out please?
I have the same scenario here, where I want to use the same ContentType.
I have reviewed the config on Comm. Channel and the module (TransformationBean) is set according to what Sonam put here… Transform.ContentType -> application/x-www-form-urlencoded
But when the message is transferred, the content is not changed and I get a “Bad Request” error.
When Sonam had a ‘Delivered’ message, mine is getting cancelled and ContentType is still application/xml.
HTTP POST params OK
error
I can’t find more details of this error…
Anyone has a suggestion?
Thanks in advance!
Hi Luiz
I am facing the same issue.
Can you please share the solution?
Regards
Amarnath M