Módulo de este artículo: Integration Flow Helper
Expresiones Camel Simple en SAP CPI: headers, propiedades y ${…} con ejemplos
Cómo funcionan las expresiones Camel Simple en SAP CPI: ${header.x}, ${property.x}, ${in.body}, fechas, el orden del Content Modifier, condiciones de Router y errores que no devuelven nada.

Casi todos los valores dinámicos de un iFlow de SAP Cloud Integration (SAP CPI) se escriben en Simple, el lenguaje de expresiones de Apache Camel: un header en la dirección de un receptor, una propiedad en un Content Modifier, una fecha en un nombre de archivo, una condición en un Router. La sintaxis es corta, ${…}, y es fácil equivocarse un poco sin darse cuenta.
Este artículo repasa las expresiones que usarás a diario, el orden en que un Content Modifier las evalúa, la diferencia entre headers y exchange properties, y los errores que hacen que una expresión no devuelva nada sin avisar.
Qué es una expresión Simple en SAP CPI
SAP Integration Suite ejecuta cada iFlow sobre Apache Camel. Cuando se ejecuta un paso, Camel reemplaza cada ${…} del campo por un valor del mensaje actual: un header, una exchange property, el cuerpo o una función integrada, como la fecha actual. El texto alrededor de la expresión queda igual, así que Order-${header.orderId}.xml se convierte en Order-4711.xml.
Puedes escribir expresiones Simple en los valores de tipo Expression de un Content Modifier y en el cuerpo del mensaje, en los campos de dirección y de consulta de muchos adaptadores receptores, en las condiciones de tipo Non-XML de Router y Filter, y en campos como el asunto de un correo o el nombre de un archivo SFTP. Los parámetros externalizados se parecen, pero son otra cosa: {{receiverHost}} se reemplaza una sola vez, al desplegar el iFlow, mientras que ${…} se evalúa para cada mensaje.
Las expresiones que usarás a diario
Unas pocas expresiones cubren la mayoría de los iFlows, y se combinan libremente con texto. El cuerpo de un Content Modifier, por ejemplo, puede armar un documento XML completo a partir de headers, propiedades y funciones:
<Order>
<Id>${property.orderId}</Id>
<Customer>${header.customerId}</Customer>
<ReceivedOn>${date:now:yyyy-MM-dd}</ReceivedOn>
<Flow>${camelId}</Flow>
<MessageLog>${property.SAP_MessageProcessingLogID}</MessageLog>
</Order>| Expresión | Qué devuelve |
|---|---|
${header.orderId} | El header del mensaje orderId |
${property.orderId} | La exchange property orderId (Camel también acepta ${exchangeProperty.orderId}) |
${in.body} o ${body} | El cuerpo actual del mensaje como texto |
${date:now:yyyy-MM-dd} | La fecha de hoy con el patrón de fecha de Java indicado |
${camelId} | El nombre del integration flow en ejecución |
${property.SAP_MessageProcessingLogID} | El ID del log de procesamiento del mensaje actual |
${header.CamelHttpResponseCode} | El código de estado que devolvió la última llamada HTTP |
Cómo evalúa un Content Modifier los headers, las propiedades y el cuerpo
Un Content Modifier recorre sus pestañas en un orden fijo: primero la tabla Message Header, luego la tabla Exchange Property y después el Message Body. Dentro de cada tabla, las filas se procesan de arriba abajo.
Ese orden decide qué puede ver una expresión. Una fila de propiedad puede leer un header creado antes en el mismo Content Modifier, y el cuerpo puede usar ambos. Una fila de header no puede leer una propiedad que crea el mismo Content Modifier, porque la propiedad todavía no existe cuando se evalúa el header; en su lugar lee un valor vacío. Si lo necesitas, define la propiedad en un Content Modifier anterior o pasa el valor a la tabla de headers, que va antes.
- Tipo de origen Expression: el valor es una expresión Simple, por ejemplo
${date:now:yyyyMMdd}-${header.orderId}. - Tipo de origen Header o Property: copia otro header u otra propiedad por su nombre, sin
${…}alrededor. - Tipo de origen XPath: lee un valor de un cuerpo XML (consulta el artículo sobre XPath enlazado más abajo).
- Los tipos de origen Constant, Local Variable, Global Variable y Number Range cubren valores fijos y valores almacenados.
¿Header o exchange property? Cuál usar
Un header viaja con el mensaje. Los adaptadores receptores pueden enviar headers al sistema que llamas, y los headers cruzan una llamada ProcessDirect hacia otro iFlow. Una exchange property se queda dentro del exchange del iFlow actual y nunca se envía por sí sola a un receptor.
Dos detalles causan la mayoría de las sorpresas. Los nombres de header no distinguen mayúsculas de minúsculas, así que ${header.OrderID} y ${header.orderid} leen el mismo header. Los nombres de exchange property sí las distinguen, así que ${property.OrderID} y ${property.orderId} son dos propiedades distintas, y puede que la segunda simplemente no exista.
- Usa una propiedad para los valores que solo necesita este iFlow: IDs, contadores, indicadores, copias guardadas del payload.
- Usa un header para los valores que debe recibir un adaptador o el siguiente iFlow, y elimina los headers que no deben salir del tenant.
- No pongas valores grandes en headers: viajan con cada llamada.
Condiciones Simple en Router y Filter
En una ruta de Router o en un Filter de tipo Non-XML, la condición es una expresión Simple comparada con un valor. Los operadores habituales son =, !=, >, >=, <, <=, contains, in y regex, unidos con and u or. Los valores de texto van entre comillas simples:
${header.orderType} = 'EXPRESS'
${property.amount} > 1000 and ${header.country} in 'DE,AT,CH'
${header.CamelHttpResponseCode} != '200'Si el header o la propiedad de una condición no existe, la condición simplemente es falsa y el mensaje toma otra ruta, a menudo la predeterminada. El artículo sobre headers y propiedades desconocidos muestra cómo detectarlo antes de que llegue a producción.
Cómo ayuda Kitegra
Kitegra es una extensión de navegador para el diseñador de SAP Integration Suite. Escribe ${ o $ en un campo del diseñador y te muestra los nombres que encajan en ese punto del iFlow: headers y propiedades definidos en Content Modifiers, en scripts de Groovy y JavaScript y en otras partes del iFlow, headers y expresiones estándar de SAP y Camel, parámetros {{…}}, variables y nombres de Data Store. Un nombre que solo se define en algunas rutas aparece marcado como «Solo se define en algunas rutas».
Su panel de lint señala un ${ sin cerrar, espacios sobrantes dentro de una expresión, y headers o propiedades que nada en el iFlow define. Para las filas XPath, un payload de ejemplo también te da sugerencias de rutas, como explica el artículo sobre XPath. La extensión nunca guarda, despliega ni edita el contenido de un iFlow, y tu tenant solo cambia cuando haces clic en una de cuatro acciones con nombre, que se pueden desactivar.
Para ver los valores que tus expresiones producen de verdad, traza un mensaje paso a paso y lee los headers y las propiedades antes de cada paso.
Sin una cuenta de Kitegra funciona en 5 iFlows por módulo. El plan Free cubre 50, Starter 100 y Pro 300. En los planes de equipo, cada miembro tiene Pro, con 300 iFlows por módulo en Startup Team y sin límite en Growth Team y Scale Team. Mientras Kitegra se lanza, todas las herramientas están abiertas para cualquiera que haya iniciado sesión, también en el plan Free. Compara los planes.
Pruébalo en tu próximo iFlow
Descubre lo que hace Kitegra en el diseñador de SAP Integration Suite, o míralo junto a las demás extensiones de Chrome de Kitegra.
Preguntas frecuentes
¿Qué diferencia hay entre ${header.x} y ${property.x} en SAP CPI?
${header.x} lee un header del mensaje, que viaja con el mensaje y puede llegar a receptores y a otros iFlows. ${property.x} lee una exchange property, que se queda dentro del iFlow actual.
¿Los nombres de headers y propiedades distinguen mayúsculas de minúsculas?
Los de header no: ${header.OrderID} y ${header.orderid} leen el mismo header. Los de exchange property sí, así que ${property.OrderID} y ${property.orderId} son propiedades distintas.
¿Por qué mi header queda vacío si lo defino a partir de una propiedad en el mismo Content Modifier?
Un Content Modifier evalúa primero la tabla de headers, luego la de propiedades y después el cuerpo. Un header no puede leer una propiedad creada en el mismo paso; define la propiedad en un paso anterior.
¿Cómo pongo la fecha de hoy en un nombre de archivo o en un campo?
Usa ${date:now:yyyy-MM-dd} con cualquier patrón de fecha de Java, por ejemplo ${date:now:yyyyMMddHHmmss} para una marca de tiempo.
¿{{parameter}} es una expresión Simple?
No. {{…}} marca un parámetro externalizado, que se reemplaza una sola vez al desplegar el iFlow. Camel evalúa ${…} para cada mensaje.
¿Qué pasa si una expresión nombra un header que no existe?
Devuelve un valor vacío sin ningún error, así que el problema aparece más tarde como una ruta equivocada o un campo vacío. Una revisión de lint o un paso de control lo detecta antes.