Skip to Content
Author's profile photo Sonam Ramsinghani

Handling x-www-form-urlencoded format Using REST Adapter

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.

 

Assigned tags

      26 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo ahamad shaik
      ahamad shaik

      Hi Sonam,

       

      Great keep it up, keep updating

       

      Regards

      Ahamad Shaik

      Author's profile photo Jose Nunes
      Jose Nunes

      Hello Sonam,

      Great blog, thanks for sharing.

      One question: why use ASMA & UDF to set URL Variables instead of using JSON Expressions?

      Regards,
      JN

      Author's profile photo Sonam Ramsinghani
      Sonam Ramsinghani
      Blog Post Author

      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.

      Author's profile photo Rashmi Joshi
      Rashmi Joshi

      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

      Author's profile photo Rajesh PS
      Rajesh PS

      Hello

      Your thoughts on this please.

      https://answers.sap.com/questions/12879150/how-to-send-http-body-parameters-in-sap-po-75.html

      Author's profile photo Former Member
      Former Member

      Excellent Blog.

      Regards,

      Pradeep Kumar

      Author's profile photo Akshay Ruia
      Akshay Ruia

      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

       

       

      Author's profile photo Sonam Ramsinghani
      Sonam Ramsinghani
      Blog Post Author

      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

      Author's profile photo Dilip Kumar KrishnaDeo Pandey
      Dilip Kumar KrishnaDeo Pandey

      Hi Sonam Ramsinghani,

      • Nice blog. keep going !

       

      Thanks & Regards,

      Dilip

      Author's profile photo Rajesh PS
      Rajesh PS
      Your thoughts on this please.
      Author's profile photo Raffael Herrmann
      Raffael Herrmann

      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?

      Author's profile photo Sonam Ramsinghani
      Sonam Ramsinghani
      Blog Post Author

      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.:)

      Author's profile photo Raffael Herrmann
      Raffael Herrmann

      Hi Sonam,

       

      atleast for me the HTTP header tab worked out today. 🙂

      Author's profile photo Sonam Ramsinghani
      Sonam Ramsinghani
      Blog Post Author

      Great. Thanks for informing.:)

      Author's profile photo Rajesh PS
      Rajesh PS

       

      Your thoughts on this please.

       

      https://answers.sap.com/questions/12879150/how-to-send-http-body-parameters-in-sap-po-75.html

       

      Thanks!

      Author's profile photo Karan Chowdhury
      Karan Chowdhury

      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.

       

      Error while sending message to module processor: Sender Channel 'TMS_MG_WebIMPORT_REST_In' (ID: 7f4796ac575d37df98148b7ea46bb12d): Catching exception calling messaging system: Mapping failed in runtimeRuntime Exception when executing application mapping program com/sap/xi/tf/_Webimport_request_MM_; Details: com.sap.aii.utilxi.misc.api.BaseRuntimeException; Content is not allowed in prolog.: Runtime Exception when executing application mapping program com/sap/xi/tf/_Webimport_request_MM_; Details: com.sap.aii.utilxi.misc.api.BaseRuntimeException; Content is not allowed in prolog.: Content is not allowed in prolog.: Content is not allowed in prolog.: Content is not allowed in prolog.

       

      BR

      Karan

      Author's profile photo Sushant Shinde
      Sushant Shinde

      Hello Sonam,

       

      cant find the attached Jar, can you please share a link, so that I can download it from there.

       

      Regards,

      Sushant

       

      Author's profile photo Sunit Samudre
      Sunit Samudre

      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

       

      Author's profile photo Pavan Gurulingappa
      Pavan Gurulingappa

      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

       

      Author's profile photo Sonam Ramsinghani
      Sonam Ramsinghani
      Blog Post Author

      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.

      Author's profile photo Pavan Gurulingappa
      Pavan Gurulingappa

      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

      Author's profile photo Sonam Ramsinghani
      Sonam Ramsinghani
      Blog Post Author

      Hi Pavan,

      There is no extra configuration required apart from the one given in the blog.

      Author's profile photo Rajesh PS
      Rajesh PS

      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!

      Author's profile photo KARUNAKAR ADAPA
      KARUNAKAR ADAPA

      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.

      Author's profile photo Luiz Felipe Martin
      Luiz Felipe Martin

      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%20POST%20params%20OK

      HTTP POST params OK

      error

      error

       

       

      I can't find more details of this error...

      Anyone has a suggestion?

       

      Thanks in advance!

       

      Author's profile photo Amarnath M
      Amarnath M

      Hi Luiz

       

      I am facing the same issue.

      Can you please share the solution?

       

      Regards

      Amarnath M