Skip to Content

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.

 

25 Comments
You must be Logged on to comment or reply to a post.