This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch 
feature/CAMEL-24961-catalog-body-types-messaging-2
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 7c24ffec7eeb333f146b66b823dab205be2b050f
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Oct 22 17:51:13 2026 +0200

    CAMEL-24961: Catalog body types for mail, paho, spring-rabbitmq, pulsar, 
nats and smpp
    
    Declares the body types of the second messaging group: the mail component
    (imap, imaps, pop3, pop3s, smtp and smtps), paho, spring-rabbitmq, pulsar,
    nats and smpp (smpp and smpps). All were checked at runtime with camel run:
    GreenMail for mail, camel infra for mosquitto, rabbitmq, pulsar and nats, 
and
    the jSMPP simulator for smpp.
    
    Fixes the doc prose about the body: the nats consumer replies only with
    exchangePattern=InOut and the producer gets the reply as bytes, the mail
    producer reads the body as text and sends a MimeMessage as it is, the split
    of mail attachments always gives their content as the body, and the smpp
    page and the CamelSmppEncoding header say how a body becomes the short
    message.
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../org/apache/camel/catalog/components/imap.json  |  5 ++
 .../org/apache/camel/catalog/components/imaps.json |  5 ++
 .../org/apache/camel/catalog/components/nats.json  |  6 ++
 .../org/apache/camel/catalog/components/paho.json  |  5 ++
 .../org/apache/camel/catalog/components/pop3.json  |  5 ++
 .../org/apache/camel/catalog/components/pop3s.json |  5 ++
 .../apache/camel/catalog/components/pulsar.json    |  5 ++
 .../org/apache/camel/catalog/components/smpp.json  |  7 +-
 .../org/apache/camel/catalog/components/smpps.json |  7 +-
 .../org/apache/camel/catalog/components/smtp.json  |  5 ++
 .../org/apache/camel/catalog/components/smtps.json |  5 ++
 .../camel/catalog/components/spring-rabbitmq.json  |  6 ++
 .../apache/camel/catalog/docs/mail-component.adoc  | 17 ++---
 .../apache/camel/catalog/docs/nats-component.adoc  |  7 +-
 .../apache/camel/catalog/docs/smpp-component.adoc  | 15 +++-
 .../org/apache/camel/component/mail/imap.json      |  5 ++
 .../org/apache/camel/component/mail/imaps.json     |  5 ++
 .../org/apache/camel/component/mail/pop3.json      |  5 ++
 .../org/apache/camel/component/mail/pop3s.json     |  5 ++
 .../org/apache/camel/component/mail/smtp.json      |  5 ++
 .../org/apache/camel/component/mail/smtps.json     |  5 ++
 .../camel-mail/src/main/docs/mail-component.adoc   | 17 ++---
 .../apache/camel/component/mail/MailEndpoint.java  | 20 +++++
 .../org/apache/camel/component/nats/nats.json      |  6 ++
 .../camel-nats/src/main/docs/nats-component.adoc   |  7 +-
 .../apache/camel/component/nats/NatsEndpoint.java  | 28 +++++++
 .../org/apache/camel/component/paho/paho.json      |  5 ++
 .../apache/camel/component/paho/PahoEndpoint.java  |  8 ++
 .../org/apache/camel/component/pulsar/pulsar.json  |  5 ++
 .../camel/component/pulsar/PulsarEndpoint.java     | 15 ++++
 .../org/apache/camel/component/smpp/smpp.json      |  7 +-
 .../org/apache/camel/component/smpp/smpps.json     |  7 +-
 .../camel-smpp/src/main/docs/smpp-component.adoc   | 15 +++-
 .../apache/camel/component/smpp/SmppConstants.java | 12 +--
 .../apache/camel/component/smpp/SmppEndpoint.java  | 22 ++++++
 .../component/springrabbit/spring-rabbitmq.json    |  6 ++
 .../springrabbit/SpringRabbitMQEndpoint.java       | 33 +++++++++
 .../camel/dsl/yaml/validator/TextBodyFlowTest.java | 85 ++++++++++++++++++++++
 38 files changed, 387 insertions(+), 46 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imap.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imap.json
index 8399bb76ec5a..47a584bfbb93 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imap.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imap.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imaps.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imaps.json
index 183ccb7e3722..35c217ab9acd 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imaps.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imaps.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/nats.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/nats.json
index eca34ceb7d3c..50696e134278 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/nats.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/nats.json
@@ -80,6 +80,12 @@
     "CamelNatsDeliveryCounter": { "index": 7, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"long", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "important": true, "description": "Number of times this 
message has been delivered (1 = first, 1 then message has been redelivered)", 
"constantName": 
"org.apache.camel.component.nats.NatsConstants#NATS_DELIVERY_COUNTER" },
     "CamelNatsManualAck": { "index": 8, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"org.apache.camel.component.nats.NatsManualAck", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
manual acknowledgment handle for JetStream messages (only set when 
manualAck=true).", "constantName": 
"org.apache.camel.component.nats.NatsConstants#NATS_MANUAL_ACK" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The payload of the NATS message as a byte array, empty for a 
message without one: convert or unmarshal it" },
+    "consumerReply": { "carriers": [ "any" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOut", "carriers": [ "text", "bytes", "stream", 
"file" ] } ], "description": "Only with exchangePattern=InOut is a message with 
a reply subject answered, with the body the route ends with: text, bytes, a 
stream or a file. A Map, a POJO or no body sends no reply, and the requester 
times out" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "What converts to a byte array: text, bytes, a stream or a file. 
A Map or a POJO is sent as its toString(), and a List or no body fails: marshal 
it first" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { 
"option": "exchangePattern", "value": "InOut", "carriers": [ "bytes" ], 
"javaType": "byte[]" } ], "description": "Unchanged for a message that expects 
no reply (InOnly). A message that expects one (InOut) waits for the reply, up 
to requestTimeout, and gets its payload as a byte array" }
+  },
   "properties": {
     "topic": { "index": 0, "kind": "path", "displayName": "Topic", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.nats.NatsConfiguration", "configurationField": 
"configuration", "description": "The name of topic we want to use" },
     "connectionTimeout": { "index": 1, "kind": "parameter", "displayName": 
"Connection Timeout", "group": "common", "label": "common", "required": false, 
"type": "integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 2000, "configurationClass": 
"org.apache.camel.component.nats.NatsConfiguration", "configurationField": 
"configuration", "description": "Timeout for connection attempts. (in 
milliseconds)" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/paho.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/paho.json
index 1ee428f6b2eb..de99e56c6983 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/paho.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/paho.json
@@ -64,6 +64,11 @@
     "CamelPahoRetained": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Retain option.", "constantName": 
"org.apache.camel.component.paho.PahoConstants#CAMEL_PAHO_MSG_RETAINED" },
     "CamelPahoOverrideTopic": { "index": 4, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The name of topic to override and send to 
instead of topic specified on endpoint.", "constantName": 
"org.apache.camel.component.paho.PahoConstants#CAMEL_PAHO_OVERRIDE_TOPIC" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The payload of the MQTT message" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "What converts to a byte array: text, bytes, a stream or a file, 
sent as the payload. A Map, a POJO or no body fails: marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "topic": { "index": 0, "kind": "path", "displayName": "Topic", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Name of the topic" },
     "automaticReconnect": { "index": 1, "kind": "parameter", "displayName": 
"Automatic Reconnect", "group": "common", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.paho.PahoConfiguration", "configurationField": 
"configuration", "description": "Sets whether the client will automatically 
attempt to reconnect to the server if the conne [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3.json
index d46e065460c7..3c4eb46d823b 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3s.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3s.json
index 652f0c2be748..0dbc734fa296 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3s.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3s.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pulsar.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pulsar.json
index edd57b05efb8..a4cce15a1aaf 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pulsar.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pulsar.json
@@ -94,6 +94,11 @@
     "CamelPulsarProducerMessageDeliverAfter": { "index": 15, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Deliver the message after a given 
delayed time (millis).", "constantName": 
"org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders#DELIVER_AFTER"
 },
     "CamelPulsarProducerMessageId": { "index": 16, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "org.apache.pulsar.client.api.MessageId", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
message id the broker assigned to the published message.", "constantName": 
"org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders#PRODUCER_MESSAGE_ID"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes", "null" ], "javaType": "byte[]", 
"description": "The payload of the Pulsar message as a byte array, null for a 
message with a null value (a tombstone), with the key and the properties in 
headers: convert or unmarshal it" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "What converts to a byte array: text, bytes, a stream or a file, 
sent as the payload. Any other body is sent with Java serialization, a Map, a 
List, a number and no body too, and an object that is not Serializable fails: 
marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
also when the exchange expects a reply, with the id of the published message in 
a header" }
+  },
   "properties": {
     "persistence": { "index": 0, "kind": "path", "displayName": "Persistence", 
"group": "common", "label": "", "required": true, "type": "enum", "javaType": 
"java.lang.String", "enum": [ "persistent", "non-persistent" ], "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "Whether the topic is persistent or non-persistent" },
     "tenant": { "index": 1, "kind": "path", "displayName": "Tenant", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The tenant" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json
index dc937fb26f6a..51702b25e413 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json
@@ -82,7 +82,7 @@
     "CamelSmppDestAddrNpi": { "index": 8, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Byte", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and 
DataSm Defines the numeric plan indicator (NPI) to be used in the SME 
destination address parameters. Use the URI option sourceAddrNpi values defined 
above. Consumer: only for DataSm Defines [...]
     "CamelSmppDestAddrTon": { "index": 9, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Byte", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and 
DataSm Defines the type of number (TON) to be used in the SME destination 
address parameters. Use the sourceAddrTon URI option values defined above. 
Consumer: only for DataSm Defines the typ [...]
     "CamelSmppDoneDate": { "index": 10, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"Date", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for smsc DeliveryReceipt The time and 
date at which the short message reached it's final state. The format is as 
follows: YYMMDDhhmm.", "constantName": 
"org.apache.camel.component.smpp.SmppConstants#DONE_DATE" },
-    "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. 
Specifies the encoding (character set name) of the bytes in the message body. 
If the message body is a string then this is not relevant because Java Strings 
are always Unicode. If the body is  [...]
+    "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for SubmitSm, SubmitMulti and ReplaceSm. 
Specifies the encoding (character set name) the text of the message body is 
encoded in, as the short message. A byte array body is first read as text, in 
the charset of the exchange, unless [...]
     "CamelSmppError": { "index": 12, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String or 
Map<String, List<Map<String, Object>>>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Producer: only for SubmitMultiSm The errors which occurred by sending the 
short message(s) the form Map (messageID : (destAddr : address, error : 
errorCode)). Consumer: only for smsc DeliveryReceipt Where a [...]
     "CamelSmppClass": { "index": 13, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.jsmpp.bean.ESMClass", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "the ASM class", 
"constantName": "org.apache.camel.component.smpp.SmppConstants#ESM_CLASS" },
     "CamelSmppEsmeAddr": { "index": 14, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for AlertNotification Defines the 
destination ESME address. For mobile terminated messages, this is the directory 
number of the recipient MS.", "constantName": 
"org.apache.camel.component.smpp.SmppConstants#ESME_ADDR" },
@@ -114,6 +114,11 @@
     "CamelSmppOptionalParameter": { "index": 40, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Map<Short, Object>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Producer: only for 
SubmitSm, SubmitMulti and DataSm The optional parameter which are send to the 
SMSC. The value is converted in the following way: String - 
org.jsmpp.bean.OptionalParameter.COctetString, byte - org.jsmpp.bea [...]
     "CamelSmppSplittingPolicy": { "index": 41, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "only for SubmitSm, SubmitMulti and 
DataSm. Specifies the policy for message splitting for this exchange. Possible 
values are described in the endpoint configuration parameter 
_splittingPolicy_", "constantName": "org.apache.camel [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "bytes", "null" ], "description": 
"A short message as text decoded by its data coding, or as bytes for an 8-bit 
data coding; the text of a delivery receipt, with its fields in headers. A 
data_sm or an alert notification has no body" },
+    "producerIn": { "carriers": [ "text", "bytes", "file" ], "description": 
"The text of the short message: bytes or a file are read as text, unless an 
8-bit CamelSmppDataCoding or CamelSmppAlphabet header sends bytes as they are. 
A stream is sent empty and no body fails: convert it to text first; a Map or a 
POJO is sent as its toString(). DataSm, QuerySm and CancelSm do not read the 
body" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { 
"option": "exchangePattern", "value": "InOut", "carriers": [ "null" ] } ], 
"description": "Unchanged, with the message ids in the CamelSmppId header. When 
the exchange expects a reply (InOut), a new message with no body and only the 
result headers" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "localhost", "configurationClass": 
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField": 
"configuration", "description": "Hostname for the SMSC server to use." },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 2775, "configurationClass": 
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField": 
"configuration", "description": "Port number for the SMSC server to use." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json
index 1adce03c7ebb..39a2de9049af 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json
@@ -82,7 +82,7 @@
     "CamelSmppDestAddrNpi": { "index": 8, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Byte", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and 
DataSm Defines the numeric plan indicator (NPI) to be used in the SME 
destination address parameters. Use the URI option sourceAddrNpi values defined 
above. Consumer: only for DataSm Defines [...]
     "CamelSmppDestAddrTon": { "index": 9, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Byte", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and 
DataSm Defines the type of number (TON) to be used in the SME destination 
address parameters. Use the sourceAddrTon URI option values defined above. 
Consumer: only for DataSm Defines the typ [...]
     "CamelSmppDoneDate": { "index": 10, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"Date", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for smsc DeliveryReceipt The time and 
date at which the short message reached it's final state. The format is as 
follows: YYMMDDhhmm.", "constantName": 
"org.apache.camel.component.smpp.SmppConstants#DONE_DATE" },
-    "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. 
Specifies the encoding (character set name) of the bytes in the message body. 
If the message body is a string then this is not relevant because Java Strings 
are always Unicode. If the body is  [...]
+    "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for SubmitSm, SubmitMulti and ReplaceSm. 
Specifies the encoding (character set name) the text of the message body is 
encoded in, as the short message. A byte array body is first read as text, in 
the charset of the exchange, unless [...]
     "CamelSmppError": { "index": 12, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String or 
Map<String, List<Map<String, Object>>>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Producer: only for SubmitMultiSm The errors which occurred by sending the 
short message(s) the form Map (messageID : (destAddr : address, error : 
errorCode)). Consumer: only for smsc DeliveryReceipt Where a [...]
     "CamelSmppClass": { "index": 13, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.jsmpp.bean.ESMClass", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "the ASM class", 
"constantName": "org.apache.camel.component.smpp.SmppConstants#ESM_CLASS" },
     "CamelSmppEsmeAddr": { "index": 14, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for AlertNotification Defines the 
destination ESME address. For mobile terminated messages, this is the directory 
number of the recipient MS.", "constantName": 
"org.apache.camel.component.smpp.SmppConstants#ESME_ADDR" },
@@ -114,6 +114,11 @@
     "CamelSmppOptionalParameter": { "index": 40, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Map<Short, Object>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Producer: only for 
SubmitSm, SubmitMulti and DataSm The optional parameter which are send to the 
SMSC. The value is converted in the following way: String - 
org.jsmpp.bean.OptionalParameter.COctetString, byte - org.jsmpp.bea [...]
     "CamelSmppSplittingPolicy": { "index": 41, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "only for SubmitSm, SubmitMulti and 
DataSm. Specifies the policy for message splitting for this exchange. Possible 
values are described in the endpoint configuration parameter 
_splittingPolicy_", "constantName": "org.apache.camel [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "bytes", "null" ], "description": 
"A short message as text decoded by its data coding, or as bytes for an 8-bit 
data coding; the text of a delivery receipt, with its fields in headers. A 
data_sm or an alert notification has no body" },
+    "producerIn": { "carriers": [ "text", "bytes", "file" ], "description": 
"The text of the short message: bytes or a file are read as text, unless an 
8-bit CamelSmppDataCoding or CamelSmppAlphabet header sends bytes as they are. 
A stream is sent empty and no body fails: convert it to text first; a Map or a 
POJO is sent as its toString(). DataSm, QuerySm and CancelSm do not read the 
body" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { 
"option": "exchangePattern", "value": "InOut", "carriers": [ "null" ] } ], 
"description": "Unchanged, with the message ids in the CamelSmppId header. When 
the exchange expects a reply (InOut), a new message with no body and only the 
result headers" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "localhost", "configurationClass": 
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField": 
"configuration", "description": "Hostname for the SMSC server to use." },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 2775, "configurationClass": 
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField": 
"configuration", "description": "Port number for the SMSC server to use." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtp.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtp.json
index c2e3c9652c51..e6517c971979 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtp.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtp.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtps.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtps.json
index 4682f6a3524c..9bd4bd00f5a1 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtps.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtps.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-rabbitmq.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-rabbitmq.json
index a2afee539d79..e2ae70cd9c83 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-rabbitmq.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-rabbitmq.json
@@ -78,6 +78,12 @@
     "CamelSpringRabbitmqPriority": { "index": 18, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The message priority.", "constantName": 
"org.apache.camel.component.springrabbit.SpringRabbitMQConstants#PRIORITY" },
     "CamelSpringRabbitmqClusterId": { "index": 19, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The cluster id.", "constantName": 
"org.apache.camel.component.springrabbit.SpringRabbitMQConstants#CLUSTER_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "bytes" ], "dependsOn": [ 
"messageConverter" ], "description": "A String when the content type starts 
with text, as for text this component sends; a byte array otherwise, JSON and 
Java serialized objects too, which are not deserialized" },
+    "consumerReply": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "messageConverter" ], "byOption": [ { "option": "allowNullBody", 
"value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], 
"description": "The reply to a message with a reply-to, converted as the 
producer converts a body: a Map or a POJO fails" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "messageConverter" ], "byOption": [ { "option": "allowNullBody", 
"value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], 
"description": "Text, bytes, a stream or a file, sent as a byte array, text as 
text\/plain unless the CamelSpringRabbitmqContentType header says another type. 
A Map or a POJO fails, as it is not serialized: marshal it first" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { 
"option": "disableReplyTo", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "Unchanged for a message that expects no reply (InOnly). A 
message that expects one (InOut) gets the body of the reply as the consumer 
gives it: a String for a text content type, a byte array otherwise" }
+  },
   "properties": {
     "exchangeName": { "index": 0, "kind": "path", "displayName": "Exchange 
Name", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The exchange name 
determines the exchange to which the produced messages will be sent to. In the 
case of consumers, the exchange name determines the exchange the queue will be 
bound to. Note: to use default exchan [...]
     "connectionFactory": { "index": 1, "kind": "parameter", "displayName": 
"Connection Factory", "group": "common", "label": "common", "required": false, 
"type": "object", "javaType": 
"org.springframework.amqp.rabbit.connection.ConnectionFactory", "deprecated": 
false, "autowired": false, "secret": false, "description": "The connection 
factory to be use. A connection factory must be configured either on the 
component or endpoint." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mail-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mail-component.adoc
index c5f952ce7317..48d3f181e17b 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mail-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mail-component.adoc
@@ -189,7 +189,9 @@ trust/key store files (see `SSLNOTES.txt` in JavaMail for 
details).
 
 Camel uses the message exchange's IN body as the
 
http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeMessage.html[MimeMessage]
-text content. The body is converted to `String.class`.
+text content. The body is converted to `String.class`: bytes, a stream or a 
file are read as text, so send binary
+content as an attachment, and a Map or a POJO is sent as its `toString()`. A 
body that is a `jakarta.mail.internet.MimeMessage`
+is sent as it is, with its own recipients and subject.
 
 Camel copies all of the exchange's IN headers to the
 
http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeMessage.html[MimeMessage]
@@ -691,17 +693,8 @@ the Splitter as shown below
 </split>
 ----
 
-You can also split the attachments as byte[] to
-be stored as the message body. This is done by creating the expression
-with boolean true
-
-._Java-only: programmatic `SplitAttachmentsExpression` configuration_
-[source,java]
-----
-SplitAttachmentsExpression split = SplitAttachmentsExpression(true);
-----
-
-And then use the expression with the splitter EIP.
+Each split message has the content of one attachment as its body: a byte 
array, or a String for a text
+attachment, with the name of the attachment in the `CamelSplitAttachmentId` 
header.
 
 === Using custom SearchTerm
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/nats-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/nats-component.adoc
index 8d11c415f087..63d1ad3aaf22 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/nats-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/nats-component.adoc
@@ -116,9 +116,12 @@ 
camel.component.nats.servers=scott:tiger@someserver:4222,superman:123@someothers
 ----
 
 === Request/Reply support
-The producer supports request/reply where it can wait for an expected reply 
message.
+The producer supports request/reply: when the exchange pattern is InOut, it 
waits for the reply message, up to
+`requestTimeout`, and the payload of the reply becomes the message body, as a 
byte array.
 
-The consumer will, when routing the message is complete, send back the message 
as reply-message if required.
+The consumer sends back the message body as the reply message, when routing 
the message is complete, if the message has a
+reply subject and the consumer has `exchangePattern=InOut`. The body must 
convert to a byte array: text, bytes, a stream or a
+file. A body that does not, such as a Map, sends no reply.
 
 == Examples
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc
index 02358413bb5a..8c5525d86d6e 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc
@@ -114,6 +114,9 @@ corresponding alphabet. When deciding which alphabet to use 
in the byte
 array, the Camel SMPP component does not consider the data coding value
 (header or configuration), it only considers the specified alphabet
 (from either the header or endpoint parameter).
+The exception is an 8-bit data coding or alphabet in a header: the body is
+then sent as the bytes it converts to, as they are. The same values in the
+endpoint parameters do not do this, so a byte array body is read as text first.
 
 If some characters in the String cannot be represented in the chosen
 alphabet, they may be replaced by the question mark (`?`) symbol.
@@ -121,8 +124,10 @@ Users of the API may want to consider checking if their 
message body can be
 converted to ISO-8859-1 before passing it to the component and if not,
 setting the alphabet header to request UCS-2 encoding.
 If the alphabet
-and data coding options are not specified at all, then the component may
-try to detect the required encoding and set the data coding for you.
+and data coding options are not specified at all, the component does not
+detect the required encoding or set the data coding for you: the text is
+encoded for the SMSC default alphabet (`0`), in the `encoding` of the endpoint,
+ISO-8859-1 by default.
 
 The list of alphabet codes is specified in the SMPP specification v3.4,
 section 5.2.19.  One notable limitation of the SMPP specification is
@@ -145,8 +150,10 @@ is completed automatically.
 
 If the GSM 3.38 alphabet is used, the component will pack up to 160
 characters into the 140-byte message body.
-If an 8-bit character set is used (e.g., ISO-8859-1 for Western Europe), then 
140 characters will be
-allowed within the 140-byte message body.
+If the 8-bit alphabet (`4`) is used, then 140 bytes will be
+allowed within the 140-byte message body. Text in an 8-bit character set
+(e.g., ISO-8859-1 for Western Europe) is split by 140 bytes only with that
+alphabet; with the default alphabet, it is split by 160 characters.
 If 16 bit UCS-2 encoding is
  used, then just 70 characters fit into each 140-byte message.
 
diff --git 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imap.json
 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imap.json
index 8399bb76ec5a..47a584bfbb93 100644
--- 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imap.json
+++ 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imap.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imaps.json
 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imaps.json
index 183ccb7e3722..35c217ab9acd 100644
--- 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imaps.json
+++ 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imaps.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3.json
 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3.json
index d46e065460c7..3c4eb46d823b 100644
--- 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3.json
+++ 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3s.json
 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3s.json
index 652f0c2be748..0dbc734fa296 100644
--- 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3s.json
+++ 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3s.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtp.json
 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtp.json
index c2e3c9652c51..e6517c971979 100644
--- 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtp.json
+++ 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtp.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtps.json
 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtps.json
index 4682f6a3524c..9bd4bd00f5a1 100644
--- 
a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtps.json
+++ 
b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtps.json
@@ -95,6 +95,11 @@
     "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Deletes the messages after they have been 
processed.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_DELETE" },
     "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message ID.", "constantName": 
"org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ 
"binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", 
"carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": 
"The content of the mail an imap or pop3 consumer reads: a String for 
text\/plain, text\/html and text\/xml, a stream for another content type, and a 
jakarta.mail Multipart for a multipart mail, which converts to the text of its 
first text part, with the files [...]
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in 
the contentType: bytes, a stream or a file are read as text, so send binary 
content as an attachment, and no body sends an empty text. A jakarta.mail 
MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it 
first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
with the Message-ID of the mail in the CamelMailMessageId header" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The mail server host name" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The port number of the mail server" },
diff --git a/components/camel-mail/src/main/docs/mail-component.adoc 
b/components/camel-mail/src/main/docs/mail-component.adoc
index c5f952ce7317..48d3f181e17b 100644
--- a/components/camel-mail/src/main/docs/mail-component.adoc
+++ b/components/camel-mail/src/main/docs/mail-component.adoc
@@ -189,7 +189,9 @@ trust/key store files (see `SSLNOTES.txt` in JavaMail for 
details).
 
 Camel uses the message exchange's IN body as the
 
http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeMessage.html[MimeMessage]
-text content. The body is converted to `String.class`.
+text content. The body is converted to `String.class`: bytes, a stream or a 
file are read as text, so send binary
+content as an attachment, and a Map or a POJO is sent as its `toString()`. A 
body that is a `jakarta.mail.internet.MimeMessage`
+is sent as it is, with its own recipients and subject.
 
 Camel copies all of the exchange's IN headers to the
 
http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeMessage.html[MimeMessage]
@@ -691,17 +693,8 @@ the Splitter as shown below
 </split>
 ----
 
-You can also split the attachments as byte[] to
-be stored as the message body. This is done by creating the expression
-with boolean true
-
-._Java-only: programmatic `SplitAttachmentsExpression` configuration_
-[source,java]
-----
-SplitAttachmentsExpression split = SplitAttachmentsExpression(true);
-----
-
-And then use the expression with the splitter EIP.
+Each split message has the content of one attachment as its body: a byte 
array, or a String for a text
+attachment, with the name of the attachment in the `CamelSplitAttachmentId` 
header.
 
 === Using custom SearchTerm
 
diff --git 
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
 
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
index 1c52a0a92ae5..45b3fb1dcb48 100644
--- 
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
+++ 
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
@@ -26,6 +26,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.camel.spi.HeaderFilterStrategyAware;
@@ -47,6 +50,23 @@ import static 
org.apache.camel.component.mail.MailConstants.MAIL_HANDLE_DUPLICAT
 @UriEndpoint(firstVersion = "1.0.0", scheme = 
"imap,imaps,pop3,pop3s,smtp,smtps", title = "IMAP,IMAPS,POP3,POP3S,SMTP,SMTPS",
              syntax = "imap:host:port", alternativeSyntax = 
"imap:username:password@host:port",
              category = { Category.MAIL }, headersClass = MailConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.TEXT, Carrier.STREAM, 
Carrier.POJO }, dependsOn = "binding",
+                                   byOption = @BodyType.When(option = 
"mapMailMessage", value = "false",
+                                                             carriers = 
Carrier.POJO, javaType = "jakarta.mail.Message"),
+                                   description = "The content of the mail an 
imap or pop3 consumer reads: a String for"
+                                                 + " text/plain, text/html and 
text/xml, a stream for another content type,"
+                                                 + " and a jakarta.mail 
Multipart for a multipart mail, which converts to the"
+                                                 + " text of its first text 
part, with the files in the attachments. The"
+                                                 + " jakarta.mail.Message 
itself with mapMailMessage=false"),
+           producerIn = @BodyType(value = { Carrier.NULL, Carrier.TEXT, 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE },
+                                  dependsOn = "binding",
+                                  description = "The text of the mail smtp 
sends, in the contentType: bytes, a stream or a"
+                                                + " file are read as text, so 
send binary content as an attachment, and no"
+                                                + " body sends an empty text. 
A jakarta.mail MimeMessage is sent as it is,"
+                                                + " and a Map or a POJO as its 
toString(): marshal it first"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   description = "Unchanged, with the 
Message-ID of the mail in the CamelMailMessageId"
+                                                 + " header"))
 public class MailEndpoint extends ScheduledPollEndpoint implements 
HeaderFilterStrategyAware, EndpointServiceLocation {
 
     @UriParam(defaultValue = "" + MailConsumer.DEFAULT_CONSUMER_DELAY, 
javaType = "java.time.Duration",
diff --git 
a/components/camel-nats/src/generated/resources/META-INF/org/apache/camel/component/nats/nats.json
 
b/components/camel-nats/src/generated/resources/META-INF/org/apache/camel/component/nats/nats.json
index eca34ceb7d3c..50696e134278 100644
--- 
a/components/camel-nats/src/generated/resources/META-INF/org/apache/camel/component/nats/nats.json
+++ 
b/components/camel-nats/src/generated/resources/META-INF/org/apache/camel/component/nats/nats.json
@@ -80,6 +80,12 @@
     "CamelNatsDeliveryCounter": { "index": 7, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"long", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "important": true, "description": "Number of times this 
message has been delivered (1 = first, 1 then message has been redelivered)", 
"constantName": 
"org.apache.camel.component.nats.NatsConstants#NATS_DELIVERY_COUNTER" },
     "CamelNatsManualAck": { "index": 8, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"org.apache.camel.component.nats.NatsManualAck", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
manual acknowledgment handle for JetStream messages (only set when 
manualAck=true).", "constantName": 
"org.apache.camel.component.nats.NatsConstants#NATS_MANUAL_ACK" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The payload of the NATS message as a byte array, empty for a 
message without one: convert or unmarshal it" },
+    "consumerReply": { "carriers": [ "any" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOut", "carriers": [ "text", "bytes", "stream", 
"file" ] } ], "description": "Only with exchangePattern=InOut is a message with 
a reply subject answered, with the body the route ends with: text, bytes, a 
stream or a file. A Map, a POJO or no body sends no reply, and the requester 
times out" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "What converts to a byte array: text, bytes, a stream or a file. 
A Map or a POJO is sent as its toString(), and a List or no body fails: marshal 
it first" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { 
"option": "exchangePattern", "value": "InOut", "carriers": [ "bytes" ], 
"javaType": "byte[]" } ], "description": "Unchanged for a message that expects 
no reply (InOnly). A message that expects one (InOut) waits for the reply, up 
to requestTimeout, and gets its payload as a byte array" }
+  },
   "properties": {
     "topic": { "index": 0, "kind": "path", "displayName": "Topic", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.nats.NatsConfiguration", "configurationField": 
"configuration", "description": "The name of topic we want to use" },
     "connectionTimeout": { "index": 1, "kind": "parameter", "displayName": 
"Connection Timeout", "group": "common", "label": "common", "required": false, 
"type": "integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 2000, "configurationClass": 
"org.apache.camel.component.nats.NatsConfiguration", "configurationField": 
"configuration", "description": "Timeout for connection attempts. (in 
milliseconds)" },
diff --git a/components/camel-nats/src/main/docs/nats-component.adoc 
b/components/camel-nats/src/main/docs/nats-component.adoc
index 8d11c415f087..63d1ad3aaf22 100644
--- a/components/camel-nats/src/main/docs/nats-component.adoc
+++ b/components/camel-nats/src/main/docs/nats-component.adoc
@@ -116,9 +116,12 @@ 
camel.component.nats.servers=scott:tiger@someserver:4222,superman:123@someothers
 ----
 
 === Request/Reply support
-The producer supports request/reply where it can wait for an expected reply 
message.
+The producer supports request/reply: when the exchange pattern is InOut, it 
waits for the reply message, up to
+`requestTimeout`, and the payload of the reply becomes the message body, as a 
byte array.
 
-The consumer will, when routing the message is complete, send back the message 
as reply-message if required.
+The consumer sends back the message body as the reply message, when routing 
the message is complete, if the message has a
+reply subject and the consumer has `exchangePattern=InOut`. The body must 
convert to a byte array: text, bytes, a stream or a
+file. A body that does not, such as a Map, sends no reply.
 
 == Examples
 
diff --git 
a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsEndpoint.java
 
b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsEndpoint.java
index ed1aaa74511e..2d95d008a104 100644
--- 
a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsEndpoint.java
+++ 
b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsEndpoint.java
@@ -31,6 +31,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.MultipleConsumersSupport;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.camel.spi.HeaderFilterStrategyAware;
@@ -45,6 +48,31 @@ import org.apache.camel.util.ObjectHelper;
  */
 @UriEndpoint(firstVersion = "2.17.0", scheme = "nats", title = "Nats", syntax 
= "nats:topic", category = { Category.MESSAGING },
              headersClass = NatsConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]",
+                                   description = "The payload of the NATS 
message as a byte array, empty for a message"
+                                                 + " without one: convert or 
unmarshal it"),
+           consumerReply = @BodyType(value = Carrier.ANY,
+                                     byOption = @BodyType.When(option = 
"exchangePattern", value = "InOut",
+                                                               carriers = {
+                                                                       
Carrier.TEXT, Carrier.BYTES, Carrier.STREAM,
+                                                                       
Carrier.FILE }),
+                                     description = "Only with 
exchangePattern=InOut is a message with a reply subject"
+                                                   + " answered, with the body 
the route ends with: text, bytes, a stream or a"
+                                                   + " file. A Map, a POJO or 
no body sends no reply, and the requester"
+                                                   + " times out"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  description = "What converts to a byte 
array: text, bytes, a stream or a file. A Map or a"
+                                                + " POJO is sent as its 
toString(), and a List or no body fails: marshal it"
+                                                + " first"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN,
+                                   byOption = {
+                                           @BodyType.When(option = 
"exchangePattern", value = "InOnly",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"exchangePattern", value = "InOut",
+                                                          carriers = 
Carrier.BYTES, javaType = "byte[]") },
+                                   description = "Unchanged for a message that 
expects no reply (InOnly). A message that"
+                                                 + " expects one (InOut) waits 
for the reply, up to requestTimeout, and gets"
+                                                 + " its payload as a byte 
array"))
 public class NatsEndpoint extends DefaultEndpoint
         implements MultipleConsumersSupport, HeaderFilterStrategyAware, 
EndpointServiceLocation {
 
diff --git 
a/components/camel-paho/src/generated/resources/META-INF/org/apache/camel/component/paho/paho.json
 
b/components/camel-paho/src/generated/resources/META-INF/org/apache/camel/component/paho/paho.json
index 1ee428f6b2eb..de99e56c6983 100644
--- 
a/components/camel-paho/src/generated/resources/META-INF/org/apache/camel/component/paho/paho.json
+++ 
b/components/camel-paho/src/generated/resources/META-INF/org/apache/camel/component/paho/paho.json
@@ -64,6 +64,11 @@
     "CamelPahoRetained": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Retain option.", "constantName": 
"org.apache.camel.component.paho.PahoConstants#CAMEL_PAHO_MSG_RETAINED" },
     "CamelPahoOverrideTopic": { "index": 4, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The name of topic to override and send to 
instead of topic specified on endpoint.", "constantName": 
"org.apache.camel.component.paho.PahoConstants#CAMEL_PAHO_OVERRIDE_TOPIC" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The payload of the MQTT message" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "What converts to a byte array: text, bytes, a stream or a file, 
sent as the payload. A Map, a POJO or no body fails: marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "topic": { "index": 0, "kind": "path", "displayName": "Topic", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Name of the topic" },
     "automaticReconnect": { "index": 1, "kind": "parameter", "displayName": 
"Automatic Reconnect", "group": "common", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.paho.PahoConfiguration", "configurationField": 
"configuration", "description": "Sets whether the client will automatically 
attempt to reconnect to the server if the conne [...]
diff --git 
a/components/camel-paho/src/main/java/org/apache/camel/component/paho/PahoEndpoint.java
 
b/components/camel-paho/src/main/java/org/apache/camel/component/paho/PahoEndpoint.java
index 48773c9848a2..619689ce1fcc 100644
--- 
a/components/camel-paho/src/main/java/org/apache/camel/component/paho/PahoEndpoint.java
+++ 
b/components/camel-paho/src/main/java/org/apache/camel/component/paho/PahoEndpoint.java
@@ -23,6 +23,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -42,6 +45,11 @@ import 
org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
 @UriEndpoint(firstVersion = "2.16.0", scheme = "paho", title = "Paho", 
category = { Category.MESSAGING, Category.IOT },
              syntax = "paho:topic", headersClass = PahoConstants.class)
 @Deprecated(since = "4.21")
+@BodyTypes(consumerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]", 
description = "The payload of the MQTT message"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  description = "What converts to a byte 
array: text, bytes, a stream or a file, sent as"
+                                                + " the payload. A Map, a POJO 
or no body fails: marshal it first"),
+           producerOut = @BodyType(Carrier.UNCHANGED))
 public class PahoEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     // Configuration members
diff --git 
a/components/camel-pulsar/src/generated/resources/META-INF/org/apache/camel/component/pulsar/pulsar.json
 
b/components/camel-pulsar/src/generated/resources/META-INF/org/apache/camel/component/pulsar/pulsar.json
index edd57b05efb8..a4cce15a1aaf 100644
--- 
a/components/camel-pulsar/src/generated/resources/META-INF/org/apache/camel/component/pulsar/pulsar.json
+++ 
b/components/camel-pulsar/src/generated/resources/META-INF/org/apache/camel/component/pulsar/pulsar.json
@@ -94,6 +94,11 @@
     "CamelPulsarProducerMessageDeliverAfter": { "index": 15, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Deliver the message after a given 
delayed time (millis).", "constantName": 
"org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders#DELIVER_AFTER"
 },
     "CamelPulsarProducerMessageId": { "index": 16, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "org.apache.pulsar.client.api.MessageId", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
message id the broker assigned to the published message.", "constantName": 
"org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders#PRODUCER_MESSAGE_ID"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes", "null" ], "javaType": "byte[]", 
"description": "The payload of the Pulsar message as a byte array, null for a 
message with a null value (a tombstone), with the key and the properties in 
headers: convert or unmarshal it" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "What converts to a byte array: text, bytes, a stream or a file, 
sent as the payload. Any other body is sent with Java serialization, a Map, a 
List, a number and no body too, and an object that is not Serializable fails: 
marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, 
also when the exchange expects a reply, with the id of the published message in 
a header" }
+  },
   "properties": {
     "persistence": { "index": 0, "kind": "path", "displayName": "Persistence", 
"group": "common", "label": "", "required": true, "type": "enum", "javaType": 
"java.lang.String", "enum": [ "persistent", "non-persistent" ], "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "Whether the topic is persistent or non-persistent" },
     "tenant": { "index": 1, "kind": "path", "displayName": "Tenant", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The tenant" },
diff --git 
a/components/camel-pulsar/src/main/java/org/apache/camel/component/pulsar/PulsarEndpoint.java
 
b/components/camel-pulsar/src/main/java/org/apache/camel/component/pulsar/PulsarEndpoint.java
index fd6de025b5ba..fd5fdb1ee8c0 100644
--- 
a/components/camel-pulsar/src/main/java/org/apache/camel/component/pulsar/PulsarEndpoint.java
+++ 
b/components/camel-pulsar/src/main/java/org/apache/camel/component/pulsar/PulsarEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -37,6 +40,18 @@ import org.apache.pulsar.client.api.PulsarClient;
 @UriEndpoint(scheme = "pulsar", firstVersion = "2.24.0", title = "Pulsar",
              syntax = "pulsar:persistence://tenant/namespace/topic", category 
= { Category.MESSAGING },
              headersClass = PulsarMessageHeaders.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.BYTES, Carrier.NULL }, 
javaType = "byte[]",
+                                   description = "The payload of the Pulsar 
message as a byte array, null for a message with"
+                                                 + " a null value (a 
tombstone), with the key and the properties in headers:"
+                                                 + " convert or unmarshal it"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  description = "What converts to a byte 
array: text, bytes, a stream or a file, sent as the"
+                                                + " payload. Any other body is 
sent with Java serialization, a Map, a List, a"
+                                                + " number and no body too, 
and an object that is not Serializable fails:"
+                                                + " marshal it first"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   description = "Unchanged, also when the 
exchange expects a reply, with the id of the"
+                                                 + " published message in a 
header"))
 public class PulsarEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     private PulsarClient pulsarClient;
diff --git 
a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json
 
b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json
index dc937fb26f6a..51702b25e413 100644
--- 
a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json
+++ 
b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json
@@ -82,7 +82,7 @@
     "CamelSmppDestAddrNpi": { "index": 8, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Byte", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and 
DataSm Defines the numeric plan indicator (NPI) to be used in the SME 
destination address parameters. Use the URI option sourceAddrNpi values defined 
above. Consumer: only for DataSm Defines [...]
     "CamelSmppDestAddrTon": { "index": 9, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Byte", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and 
DataSm Defines the type of number (TON) to be used in the SME destination 
address parameters. Use the sourceAddrTon URI option values defined above. 
Consumer: only for DataSm Defines the typ [...]
     "CamelSmppDoneDate": { "index": 10, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"Date", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for smsc DeliveryReceipt The time and 
date at which the short message reached it's final state. The format is as 
follows: YYMMDDhhmm.", "constantName": 
"org.apache.camel.component.smpp.SmppConstants#DONE_DATE" },
-    "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. 
Specifies the encoding (character set name) of the bytes in the message body. 
If the message body is a string then this is not relevant because Java Strings 
are always Unicode. If the body is  [...]
+    "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for SubmitSm, SubmitMulti and ReplaceSm. 
Specifies the encoding (character set name) the text of the message body is 
encoded in, as the short message. A byte array body is first read as text, in 
the charset of the exchange, unless [...]
     "CamelSmppError": { "index": 12, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String or 
Map<String, List<Map<String, Object>>>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Producer: only for SubmitMultiSm The errors which occurred by sending the 
short message(s) the form Map (messageID : (destAddr : address, error : 
errorCode)). Consumer: only for smsc DeliveryReceipt Where a [...]
     "CamelSmppClass": { "index": 13, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.jsmpp.bean.ESMClass", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "the ASM class", 
"constantName": "org.apache.camel.component.smpp.SmppConstants#ESM_CLASS" },
     "CamelSmppEsmeAddr": { "index": 14, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for AlertNotification Defines the 
destination ESME address. For mobile terminated messages, this is the directory 
number of the recipient MS.", "constantName": 
"org.apache.camel.component.smpp.SmppConstants#ESME_ADDR" },
@@ -114,6 +114,11 @@
     "CamelSmppOptionalParameter": { "index": 40, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Map<Short, Object>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Producer: only for 
SubmitSm, SubmitMulti and DataSm The optional parameter which are send to the 
SMSC. The value is converted in the following way: String - 
org.jsmpp.bean.OptionalParameter.COctetString, byte - org.jsmpp.bea [...]
     "CamelSmppSplittingPolicy": { "index": 41, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "only for SubmitSm, SubmitMulti and 
DataSm. Specifies the policy for message splitting for this exchange. Possible 
values are described in the endpoint configuration parameter 
_splittingPolicy_", "constantName": "org.apache.camel [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "bytes", "null" ], "description": 
"A short message as text decoded by its data coding, or as bytes for an 8-bit 
data coding; the text of a delivery receipt, with its fields in headers. A 
data_sm or an alert notification has no body" },
+    "producerIn": { "carriers": [ "text", "bytes", "file" ], "description": 
"The text of the short message: bytes or a file are read as text, unless an 
8-bit CamelSmppDataCoding or CamelSmppAlphabet header sends bytes as they are. 
A stream is sent empty and no body fails: convert it to text first; a Map or a 
POJO is sent as its toString(). DataSm, QuerySm and CancelSm do not read the 
body" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { 
"option": "exchangePattern", "value": "InOut", "carriers": [ "null" ] } ], 
"description": "Unchanged, with the message ids in the CamelSmppId header. When 
the exchange expects a reply (InOut), a new message with no body and only the 
result headers" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "localhost", "configurationClass": 
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField": 
"configuration", "description": "Hostname for the SMSC server to use." },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 2775, "configurationClass": 
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField": 
"configuration", "description": "Port number for the SMSC server to use." },
diff --git 
a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json
 
b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json
index 1adce03c7ebb..39a2de9049af 100644
--- 
a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json
+++ 
b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json
@@ -82,7 +82,7 @@
     "CamelSmppDestAddrNpi": { "index": 8, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Byte", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and 
DataSm Defines the numeric plan indicator (NPI) to be used in the SME 
destination address parameters. Use the URI option sourceAddrNpi values defined 
above. Consumer: only for DataSm Defines [...]
     "CamelSmppDestAddrTon": { "index": 9, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Byte", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and 
DataSm Defines the type of number (TON) to be used in the SME destination 
address parameters. Use the sourceAddrTon URI option values defined above. 
Consumer: only for DataSm Defines the typ [...]
     "CamelSmppDoneDate": { "index": 10, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"Date", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for smsc DeliveryReceipt The time and 
date at which the short message reached it's final state. The format is as 
follows: YYMMDDhhmm.", "constantName": 
"org.apache.camel.component.smpp.SmppConstants#DONE_DATE" },
-    "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. 
Specifies the encoding (character set name) of the bytes in the message body. 
If the message body is a string then this is not relevant because Java Strings 
are always Unicode. If the body is  [...]
+    "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for SubmitSm, SubmitMulti and ReplaceSm. 
Specifies the encoding (character set name) the text of the message body is 
encoded in, as the short message. A byte array body is first read as text, in 
the charset of the exchange, unless [...]
     "CamelSmppError": { "index": 12, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String or 
Map<String, List<Map<String, Object>>>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Producer: only for SubmitMultiSm The errors which occurred by sending the 
short message(s) the form Map (messageID : (destAddr : address, error : 
errorCode)). Consumer: only for smsc DeliveryReceipt Where a [...]
     "CamelSmppClass": { "index": 13, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.jsmpp.bean.ESMClass", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "the ASM class", 
"constantName": "org.apache.camel.component.smpp.SmppConstants#ESM_CLASS" },
     "CamelSmppEsmeAddr": { "index": 14, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "only for AlertNotification Defines the 
destination ESME address. For mobile terminated messages, this is the directory 
number of the recipient MS.", "constantName": 
"org.apache.camel.component.smpp.SmppConstants#ESME_ADDR" },
@@ -114,6 +114,11 @@
     "CamelSmppOptionalParameter": { "index": 40, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Map<Short, Object>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Producer: only for 
SubmitSm, SubmitMulti and DataSm The optional parameter which are send to the 
SMSC. The value is converted in the following way: String - 
org.jsmpp.bean.OptionalParameter.COctetString, byte - org.jsmpp.bea [...]
     "CamelSmppSplittingPolicy": { "index": 41, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "only for SubmitSm, SubmitMulti and 
DataSm. Specifies the policy for message splitting for this exchange. Possible 
values are described in the endpoint configuration parameter 
_splittingPolicy_", "constantName": "org.apache.camel [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "bytes", "null" ], "description": 
"A short message as text decoded by its data coding, or as bytes for an 8-bit 
data coding; the text of a delivery receipt, with its fields in headers. A 
data_sm or an alert notification has no body" },
+    "producerIn": { "carriers": [ "text", "bytes", "file" ], "description": 
"The text of the short message: bytes or a file are read as text, unless an 
8-bit CamelSmppDataCoding or CamelSmppAlphabet header sends bytes as they are. 
A stream is sent empty and no body fails: convert it to text first; a Map or a 
POJO is sent as its toString(). DataSm, QuerySm and CancelSm do not read the 
body" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { 
"option": "exchangePattern", "value": "InOut", "carriers": [ "null" ] } ], 
"description": "Unchanged, with the message ids in the CamelSmppId header. When 
the exchange expects a reply (InOut), a new message with no body and only the 
result headers" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "localhost", "configurationClass": 
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField": 
"configuration", "description": "Hostname for the SMSC server to use." },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 2775, "configurationClass": 
"org.apache.camel.component.smpp.SmppConfiguration", "configurationField": 
"configuration", "description": "Port number for the SMSC server to use." },
diff --git a/components/camel-smpp/src/main/docs/smpp-component.adoc 
b/components/camel-smpp/src/main/docs/smpp-component.adoc
index 02358413bb5a..8c5525d86d6e 100644
--- a/components/camel-smpp/src/main/docs/smpp-component.adoc
+++ b/components/camel-smpp/src/main/docs/smpp-component.adoc
@@ -114,6 +114,9 @@ corresponding alphabet. When deciding which alphabet to use 
in the byte
 array, the Camel SMPP component does not consider the data coding value
 (header or configuration), it only considers the specified alphabet
 (from either the header or endpoint parameter).
+The exception is an 8-bit data coding or alphabet in a header: the body is
+then sent as the bytes it converts to, as they are. The same values in the
+endpoint parameters do not do this, so a byte array body is read as text first.
 
 If some characters in the String cannot be represented in the chosen
 alphabet, they may be replaced by the question mark (`?`) symbol.
@@ -121,8 +124,10 @@ Users of the API may want to consider checking if their 
message body can be
 converted to ISO-8859-1 before passing it to the component and if not,
 setting the alphabet header to request UCS-2 encoding.
 If the alphabet
-and data coding options are not specified at all, then the component may
-try to detect the required encoding and set the data coding for you.
+and data coding options are not specified at all, the component does not
+detect the required encoding or set the data coding for you: the text is
+encoded for the SMSC default alphabet (`0`), in the `encoding` of the endpoint,
+ISO-8859-1 by default.
 
 The list of alphabet codes is specified in the SMPP specification v3.4,
 section 5.2.19.  One notable limitation of the SMPP specification is
@@ -145,8 +150,10 @@ is completed automatically.
 
 If the GSM 3.38 alphabet is used, the component will pack up to 160
 characters into the 140-byte message body.
-If an 8-bit character set is used (e.g., ISO-8859-1 for Western Europe), then 
140 characters will be
-allowed within the 140-byte message body.
+If the 8-bit alphabet (`4`) is used, then 140 bytes will be
+allowed within the 140-byte message body. Text in an 8-bit character set
+(e.g., ISO-8859-1 for Western Europe) is split by 140 bytes only with that
+alphabet; with the default alphabet, it is split by 160 characters.
 If 16 bit UCS-2 encoding is
  used, then just 70 characters fit into each 140-byte message.
 
diff --git 
a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConstants.java
 
b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConstants.java
index 56736b1bb880..ddb349a4a0d5 100644
--- 
a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConstants.java
+++ 
b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConstants.java
@@ -80,12 +80,12 @@ public interface SmppConstants {
               javaType = "Date")
     String DONE_DATE = "CamelSmppDoneDate";
     @Metadata(label = "producer", description = "*only for SubmitSm,\n" +
-                                                "SubmitMulti and DataSm*.  
Specifies the encoding (character set name) of\n" +
-                                                "the bytes in the message 
body.  If the message body is a string then\n" +
-                                                "this is not relevant because 
Java Strings are always Unicode.  If the\n" +
-                                                "body is a byte array then 
this header can be used to indicate that it is\n" +
-                                                "ISO-8859-1 or some other 
value.  Default value is specified by the\n" +
-                                                "endpoint configuration 
parameter _encoding_",
+                                                "SubmitMulti and ReplaceSm*.  
Specifies the encoding (character set name)\n" +
+                                                "the text of the message body 
is encoded in, as the short message.  A\n" +
+                                                "byte array body is first read 
as text, in the charset of the exchange,\n" +
+                                                "unless an 8-bit data coding 
or alphabet header sends it as it is.\n" +
+                                                "Default value is specified by 
the endpoint configuration parameter\n" +
+                                                "_encoding_",
               javaType = "String")
     String ENCODING = "CamelSmppEncoding";
     @Metadata(description = "*Producer:* *only for SubmitMultiSm* The errors 
which\n" +
diff --git 
a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppEndpoint.java
 
b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppEndpoint.java
index 84771fb69c4a..584ea1f40275 100644
--- 
a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppEndpoint.java
+++ 
b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppEndpoint.java
@@ -23,6 +23,9 @@ import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -35,6 +38,25 @@ import org.jsmpp.bean.DeliverSm;
  */
 @UriEndpoint(firstVersion = "2.2.0", scheme = "smpp,smpps", title = "SMPP", 
syntax = "smpp:host:port",
              category = { Category.MOBILE }, lenientProperties = true, 
headersClass = SmppConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.NULL },
+                                   description = "A short message as text 
decoded by its data coding, or as bytes for an"
+                                                 + " 8-bit data coding; the 
text of a delivery receipt, with its fields in"
+                                                 + " headers. A data_sm or an 
alert notification has no body"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.FILE },
+                                  description = "The text of the short 
message: bytes or a file are read as text, unless an"
+                                                + " 8-bit CamelSmppDataCoding 
or CamelSmppAlphabet header sends bytes as they"
+                                                + " are. A stream is sent 
empty and no body fails: convert it to text first;"
+                                                + " a Map or a POJO is sent as 
its toString(). DataSm, QuerySm and CancelSm do"
+                                                + " not read the body"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN,
+                                   byOption = {
+                                           @BodyType.When(option = 
"exchangePattern", value = "InOnly",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"exchangePattern", value = "InOut",
+                                                          carriers = 
Carrier.NULL) },
+                                   description = "Unchanged, with the message 
ids in the CamelSmppId header. When the"
+                                                 + " exchange expects a reply 
(InOut), a new message with no body and only the"
+                                                 + " result headers"))
 public class SmppEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     private SmppBinding binding;
diff --git 
a/components/camel-spring-parent/camel-spring-rabbitmq/src/generated/resources/META-INF/org/apache/camel/component/springrabbit/spring-rabbitmq.json
 
b/components/camel-spring-parent/camel-spring-rabbitmq/src/generated/resources/META-INF/org/apache/camel/component/springrabbit/spring-rabbitmq.json
index a2afee539d79..e2ae70cd9c83 100644
--- 
a/components/camel-spring-parent/camel-spring-rabbitmq/src/generated/resources/META-INF/org/apache/camel/component/springrabbit/spring-rabbitmq.json
+++ 
b/components/camel-spring-parent/camel-spring-rabbitmq/src/generated/resources/META-INF/org/apache/camel/component/springrabbit/spring-rabbitmq.json
@@ -78,6 +78,12 @@
     "CamelSpringRabbitmqPriority": { "index": 18, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The message priority.", "constantName": 
"org.apache.camel.component.springrabbit.SpringRabbitMQConstants#PRIORITY" },
     "CamelSpringRabbitmqClusterId": { "index": 19, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The cluster id.", "constantName": 
"org.apache.camel.component.springrabbit.SpringRabbitMQConstants#CLUSTER_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "bytes" ], "dependsOn": [ 
"messageConverter" ], "description": "A String when the content type starts 
with text, as for text this component sends; a byte array otherwise, JSON and 
Java serialized objects too, which are not deserialized" },
+    "consumerReply": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "messageConverter" ], "byOption": [ { "option": "allowNullBody", 
"value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], 
"description": "The reply to a message with a reply-to, converted as the 
producer converts a body: a Map or a POJO fails" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "messageConverter" ], "byOption": [ { "option": "allowNullBody", 
"value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], 
"description": "Text, bytes, a stream or a file, sent as a byte array, text as 
text\/plain unless the CamelSpringRabbitmqContentType header says another type. 
A Map or a POJO fails, as it is not serialized: marshal it first" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { 
"option": "disableReplyTo", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "Unchanged for a message that expects no reply (InOnly). A 
message that expects one (InOut) gets the body of the reply as the consumer 
gives it: a String for a text content type, a byte array otherwise" }
+  },
   "properties": {
     "exchangeName": { "index": 0, "kind": "path", "displayName": "Exchange 
Name", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The exchange name 
determines the exchange to which the produced messages will be sent to. In the 
case of consumers, the exchange name determines the exchange the queue will be 
bound to. Note: to use default exchan [...]
     "connectionFactory": { "index": 1, "kind": "parameter", "displayName": 
"Connection Factory", "group": "common", "label": "common", "required": false, 
"type": "object", "javaType": 
"org.springframework.amqp.rabbit.connection.ConnectionFactory", "deprecated": 
false, "autowired": false, "secret": false, "description": "The connection 
factory to be use. A connection factory must be configured either on the 
component or endpoint." },
diff --git 
a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQEndpoint.java
 
b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQEndpoint.java
index 25343414cffe..ba560b46b8c7 100644
--- 
a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQEndpoint.java
+++ 
b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQEndpoint.java
@@ -26,6 +26,9 @@ import org.apache.camel.Exchange;
 import org.apache.camel.PollingConsumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -57,6 +60,36 @@ import static 
org.apache.camel.component.springrabbit.SpringRabbitMQConstants.DI
 @UriEndpoint(firstVersion = "3.8.0", scheme = "spring-rabbitmq", title = 
"Spring RabbitMQ",
              syntax = "spring-rabbitmq:exchangeName",
              category = { Category.MESSAGING }, headersClass = 
SpringRabbitMQConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.TEXT, Carrier.BYTES }, 
dependsOn = "messageConverter",
+                                   description = "A String when the content 
type starts with text, as for text this"
+                                                 + " component sends; a byte 
array otherwise, JSON and Java serialized objects"
+                                                 + " too, which are not 
deserialized"),
+           consumerReply = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                     dependsOn = "messageConverter",
+                                     byOption = @BodyType.When(option = 
"allowNullBody", value = "true",
+                                                               carriers = {
+                                                                       
Carrier.NULL, Carrier.TEXT, Carrier.BYTES,
+                                                                       
Carrier.STREAM, Carrier.FILE }),
+                                     description = "The reply to a message 
with a reply-to, converted as the producer"
+                                                   + " converts a body: a Map 
or a POJO fails"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  dependsOn = "messageConverter",
+                                  byOption = @BodyType.When(option = 
"allowNullBody", value = "true",
+                                                            carriers = {
+                                                                    
Carrier.NULL, Carrier.TEXT, Carrier.BYTES,
+                                                                    
Carrier.STREAM, Carrier.FILE }),
+                                  description = "Text, bytes, a stream or a 
file, sent as a byte array, text as text/plain"
+                                                + " unless the 
CamelSpringRabbitmqContentType header says another type. A Map"
+                                                + " or a POJO fails, as it is 
not serialized: marshal it first"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN,
+                                   byOption = {
+                                           @BodyType.When(option = 
"exchangePattern", value = "InOnly",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"disableReplyTo", value = "true",
+                                                          carriers = 
Carrier.UNCHANGED) },
+                                   description = "Unchanged for a message that 
expects no reply (InOnly). A message that"
+                                                 + " expects one (InOut) gets 
the body of the reply as the consumer gives it:"
+                                                 + " a String for a text 
content type, a byte array otherwise"))
 public class SpringRabbitMQEndpoint extends DefaultEndpoint implements 
AsyncEndpoint, EndpointServiceLocation {
 
     public static final String ARG_PREFIX = "arg.";
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java
index 620acf8bab55..24da4237401c 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java
@@ -1406,6 +1406,91 @@ public class TextBodyFlowTest {
                 .anySatisfy(m -> assertThat(m).contains("to: google-pubsub 
needs the body as text or bytes"));
     }
 
+    @Test
+    public void testTheBodyOfMessaging() {
+        // the paho consumer gives bytes, so a field read needs an unmarshal; 
pulsar and smtp send what converts to
+        // bytes or text, so parsed data must be marshalled first, and so must 
the reply of a nats consumer that answers
+        // (InOut); the converter of spring-rabbitmq may be set on the 
component, and an imap mail may be text, a stream
+        // or a multipart, which say nothing
+        String yaml = """
+                - route:
+                    id: mqtt
+                    from:
+                      uri: paho:orders
+                      steps:
+                        - setHeader:
+                            name: id
+                            simple: ${body[id]}
+                - route:
+                    id: publish
+                    from:
+                      uri: timer:tick
+                      steps:
+                        - setBody:
+                            constant: '{"id": 1}'
+                        - unmarshal:
+                            json: {}
+                        - to: pulsar:persistent://public/default/orders
+                - route:
+                    id: service
+                    from:
+                      uri: nats:orders
+                      parameters:
+                        exchangePattern: InOut
+                      steps:
+                        - setBody:
+                            constant: '{"id": 1}'
+                        - unmarshal:
+                            json: {}
+                - route:
+                    id: listener
+                    from:
+                      uri: nats:events
+                      steps:
+                        - setBody:
+                            constant: '{"id": 1}'
+                        - unmarshal:
+                            json: {}
+                - route:
+                    id: rabbit
+                    from:
+                      uri: timer:tick
+                      steps:
+                        - setBody:
+                            constant: '{"id": 1}'
+                        - unmarshal:
+                            json: {}
+                        - to: spring-rabbitmq:orders
+                - route:
+                    id: mail
+                    from:
+                      uri: timer:tick
+                      steps:
+                        - setBody:
+                            constant: '{"id": 1}'
+                        - unmarshal:
+                            json: {}
+                        - to: smtp://[email protected]
+                - route:
+                    id: inbox
+                    from:
+                      uri: imap://localhost
+                      steps:
+                        - setHeader:
+                            name: id
+                            simple: ${body[id]}
+                """;
+        assertThat(lines(yaml)).hasSize(4).anySatisfy(m -> assertThat(m)
+                .contains("route mqtt: simple reads a field of the body 
(${body[id]})")
+                .contains("the paho consumer gives it as bytes"))
+                .anySatisfy(m -> assertThat(m).contains("to: pulsar needs the 
body as text, bytes, a stream or a file"))
+                .anySatisfy(m -> assertThat(m)
+                        .contains("route service:")
+                        .contains("the body at the end of the route is the 
reply to the nats request"))
+                .anySatisfy(m -> assertThat(m)
+                        .contains("route mail: to: smtp needs the body as 
text, bytes, a stream or a file"));
+    }
+
     @Test
     public void testTheBodyOfCoreComponents() {
         // the stream consumer gives each line as text, so a field read needs 
an unmarshal, and stream:out writes text,

Reply via email to