βš™οΈSAPTools
Integration10 min read

SAP CPI Groovy Scripting: Common Patterns and Snippets

Practical Groovy script patterns for SAP Cloud Integration (CPI): reading/writing message properties, header manipulation, custom XML/JSON transformation, and error handling.

Published June 25, 2026

Advertisement

SAP CPI Groovy Scripting: Common Patterns and Snippets

Standard-defined message mapping steps in SAP Cloud Integration (CPI) cover most cases, but the moment you need conditional logic, custom validation, or a transformation not expressible in a graphical mapping, you reach for a Groovy Script step. Here are the patterns that come up constantly.

Reading and Writing the Message Body

import com.sap.gateway.ip.core.customdev.util.Message

Message processData(Message message) {
    def body = message.getBody(String) as String
    // ... transform body ...
    message.setBody(body)
    return message
}

Working with Headers and Properties

Headers and exchange properties are the two ways data travels alongside the payload through an iFlow:

Message processData(Message message) {
    def map = message.getProperties()
    def orderId = map.get("OrderId")

    // Set a header for a downstream adapter (e.g. a dynamic HTTP path)
    message.setHeader("CamelHttpPath", "/orders/" + orderId)

    // Set a property to pass data to a later step without exposing it externally
    message.setProperty("InternalRetryCount", "0")

    return message
}

Rule of thumb: use properties for data that should stay internal to the iFlow, and headers only when a downstream adapter or a specific step needs to read them (headers can leak to the receiver system depending on the adapter).

Custom JSON to XML (or Vice Versa) When Mapping Falls Short

import groovy.json.JsonSlurper
import groovy.xml.MarkupBuilder

Message processData(Message message) {
    def json = new JsonSlurper().parseText(message.getBody(String) as String)
    def writer = new StringWriter()
    def xml = new MarkupBuilder(writer)

    xml.Order {
        OrderId(json.orderId)
        Customer(json.customer.name)
    }

    message.setBody(writer.toString())
    return message
}

Error Handling Inside a Script Step

Throwing a plain exception aborts the iFlow with a generic message. Wrap it to surface something useful in Message Processing Logs:

Message processData(Message message) {
    try {
        // risky transformation
    } catch (Exception e) {
        throw new RuntimeException("Failed to transform payload: " + e.getMessage(), e)
    }
    return message
}

Common Pitfall: Script State

Don't rely on static/global variables for state between message executions β€” CPI reuses worker threads, and a script step is not guaranteed a fresh instance per message. Keep all state on the Message object (body, headers, properties) instead.

If you're scaffolding a new integration pattern from scratch, our CPI iFlow Template Generator produces sender/receiver adapter configuration plus a Groovy stub to start from, and the JSON Formatter is handy for inspecting payloads captured from Message Processing Logs before you write the transformation.

Topics:

sap cpigroovy scriptcpi message mappingintegration suite groovycpi script step