Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
328

SAP PI REST channel provides features of converting json data types in json payload. Currently SAP BTP Cloud integration xml to json conversion doesn’t have this specific feature of specific data types in json payload. This blog explains how to use generic groovy script to update json data types (Boolean, numbers)

Example xml payload:

<?xml version="1.0" encoding="UTF-8"?>

<TestMessage>

   <testBooleanField>true</testBooleanField>

   <language>en</language>

   <arraysOfFields>

      <uniqueId>12345</uniqueId>

      <activeFlag>false</activeFlag>

      <amounts>

         <decimalValue>100.34</decimalValue>

         <integerValue>10</integerValue>

      </amounts>

   </arraysOfFields>

   <arraysOfFields>

      <uniqueId>678904</uniqueId>

      <activeFlag>true</activeFlag>

      <amounts>

         <decimalValue>10.34</decimalValue>

         <integerValue>100</integerValue>

      </amounts>

   </arraysOfFields>

</TestMessage>

After we convert into json using xml to json palette function in Cloud integration:

{
   "testBooleanField":"true",
   "language":"en",
   "arraysOfFields":[
      {
         "uniqueId":"12345",
         "activeFlag":"false",
         "amounts":{
            "decimalValue":"100.34",
            "integerValue":"10"
         }
      },
      {
         "uniqueId":"678904",
         "activeFlag":"true",
         "amounts":{
            "decimalValue":"10.34",
            "integerValue":"100"
         }
      }
   ]
}

Usually json datatypes are represented in below format and also depends on api specification provided by API provider:

"testBooleanField":true,

"activeFlag":false,

 "decimalValue":100.34,

  "integerValue":10

To covert these json data types without double quotes in json, we could write specific groovy or java script within Cloud integration iflow.

This blog explains how we can use generic groovy function to achieve the same. We also need to specify json paths and data types as exchange property  

Step 1:

Create Generic groovy script and deploy:

saikrishna_kalivarapu2_0-1729133027468.png

 

Code:

import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.json.JsonSlurper;
import groovy.json.JsonOutput;
def Message processData(Message message) {   
    def payload = message.getBody(String)       
    def parsedJson = new JsonSlurper().parseText(payload)
    def properties = message.getProperties()
    def list = message.getProperty("input_list")
    def map = new HashMap()
    def listlist = list.split(",")
    for( l in listlist) {
        def a = l.trim().split(":")
        map.put(a[0].trim(),a[1].trim())
    }
    map.each { propertyName, jsonKey ->
    def keys = propertyName.split(/\./)
    def output = parsedJson["data"]
    def output_prev = parsedJson["data"]
    if(output == null){
        output = parsedJson
    }
    processfunction(output,keys,0,output_prev, jsonKey)
    }
    def modifiedJsonString = JsonOutput.toJson(parsedJson)
    message.setBody(modifiedJsonString)  
    return message
}

def Object processfunction(Object output,String[] keys, int index,Object output_prev, String jsonKey) {
   if(keys.size()<index) {
       return
   }
   if(output != null && output instanceof Map) {
       output_prev = output
       output = output.get(keys[index])
       index = index + 1
       processfunction(output,keys,index,output_prev,jsonKey)
   }
   if(output!=null && output instanceof String) {
       def convertedValue = convertToType(output,jsonKey)
       output_prev.put(keys[index-1],convertedValue)
       return
   }
   if(output != null && (output instanceof List || output instanceof Map[])) {
       output.each { item ->
           processfunction(item,keys,index,item,jsonKey)
       }
   }
}

def convertToType(value, type) {
   if (value instanceof String) {
       if (type.toLowerCase() == "integer") { return value.toInteger()}
       if (type.toLowerCase() == "boolean") { return value.toBoolean()}
       if (type.toLowerCase() == "decimal") { return value.toDouble()}
       return value
   } else {
       return value
   }
}

Step2: Test this script using integration flow

1. Set xml payload: (above xml)

saikrishna_kalivarapu2_1-1729133027471.png

2. Convert xml to json using palette function, suppress json root element and covert xml to json array (/TestMessage/arraysOfFields):

saikrishna_kalivarapu2_2-1729133027474.png

3. Use content modifier to set json data type conversions: (using exchange property)

Name = input_list

Source Type = Constant

Source Value= testBooleanField:boolean,arraysOfFields.activeFlag:boolean,arraysOfFields.amounts.decimalValue:decimal,arraysOfFields.amounts.integerValue:integer

saikrishna_kalivarapu2_3-1729133027477.png

4. Add groovy script as an external reference to this iFlow:

saikrishna_kalivarapu2_4-1729133027479.png

5. Use timer run once at the start of iFlow and deploy iflow to test it

 

We can see that result json coverted successfully:

saikrishna_kalivarapu2_5-1729133027482.png

 

To conclude, generic groovy script helps to convert json data types based on api specification by using script as well by populating json field path and types as exchange property.

1 Comment
Labels in this area