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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 8561a9b1ca3d CAMEL-26503: camel-platform-http-vertx - write a number, 
boolean, character or enum reply as text (#28984)
8561a9b1ca3d is described below

commit 8561a9b1ca3dcb6ff52844147c97f26438ccb46d
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Nov 2 22:31:14 2026 +0100

    CAMEL-26503: camel-platform-http-vertx - write a number, boolean, character 
or enum reply as text (#28984)
    
    …racter or enum reply as text
    
    The Vert.x engine wrote a reply body it did not know through the type 
converter, InputStream first and then
    ByteBuffer. NIOConverter writes an Integer, Long, Short, Float or Double in 
its binary form, so
    setBody(constant(42)) replied with the 4 bytes 00 00 00 2A; a Boolean, 
Character or enum had no converter and the
    reply failed with 500. Such a body is now written as its text, through the 
String branch, so the charset of the
    response Content-Type applies, as camel-undertow does (CAMEL-26140). A 
StringBuilder or another CharSequence also
    goes through that branch now, rather than being written in the charset of 
the exchange.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../camel/catalog/docs/platform-http-vertx.adoc    |   7 +
 .../src/main/docs/platform-http-vertx.adoc         |   7 +
 .../http/vertx/VertxPlatformHttpSupport.java       |  15 ++-
 .../VertxPlatformHttpSingleValueResponseTest.java  | 142 +++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    |   9 ++
 5 files changed, 179 insertions(+), 1 deletion(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/platform-http-vertx.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/platform-http-vertx.adoc
index 26549b7f9fb1..ee923da129a8 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/platform-http-vertx.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/platform-http-vertx.adoc
@@ -89,6 +89,13 @@ Camel `HttpMessage` as shown in the custom `Processor` below 
:
 });
 ----
 
+== Response body
+
+The body of the reply is written as text, bytes or a stream. Text is written 
in the charset that the response
+`Content-Type` declares (UTF-8 otherwise), and a number, a boolean, a 
character or an enum as its text, so
+`setBody(constant(42))` replies with `42`. A Map, a List or an object must be 
marshalled first (for example with
+`marshal().json()`), or the consumer answers `500`.
+
 == Handling large request / response payloads
 
 When large request / response payloads are expected, there is a `useStreaming` 
option, which can be enabled to improve performance.
diff --git 
a/components/camel-platform-http-vertx/src/main/docs/platform-http-vertx.adoc 
b/components/camel-platform-http-vertx/src/main/docs/platform-http-vertx.adoc
index 26549b7f9fb1..ee923da129a8 100644
--- 
a/components/camel-platform-http-vertx/src/main/docs/platform-http-vertx.adoc
+++ 
b/components/camel-platform-http-vertx/src/main/docs/platform-http-vertx.adoc
@@ -89,6 +89,13 @@ Camel `HttpMessage` as shown in the custom `Processor` below 
:
 });
 ----
 
+== Response body
+
+The body of the reply is written as text, bytes or a stream. Text is written 
in the charset that the response
+`Content-Type` declares (UTF-8 otherwise), and a number, a boolean, a 
character or an enum as its text, so
+`setBody(constant(42))` replies with `42`. A Map, a List or an object must be 
marshalled first (for example with
+`marshal().json()`), or the consumer answers `500`.
+
 == Handling large request / response payloads
 
 When large request / response payloads are expected, there is a `useStreaming` 
option, which can be enabled to improve performance.
diff --git 
a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java
 
b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java
index 20996fab4cfe..0490adf90f6f 100644
--- 
a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java
+++ 
b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java
@@ -185,7 +185,7 @@ public final class VertxPlatformHttpSupport {
         }
 
         try {
-            final Object body = toHttpResponse(ctx, 
camelExchange.getMessage(), headerFilterStrategy, muteExceptions);
+            final Object body = asText(toHttpResponse(ctx, 
camelExchange.getMessage(), headerFilterStrategy, muteExceptions));
             if (body == null) {
                 LOGGER.trace("No payload to send as reply for exchange: {}", 
camelExchange);
                 ctx.end();
@@ -216,6 +216,19 @@ public final class VertxPlatformHttpSupport {
         return promise.future();
     }
 
+    /**
+     * Text and a single value (a number, a boolean, a character or an enum) 
become a String, written as text in the
+     * charset of the response Content-Type: the type converter would write a 
number in its binary form (an Integer as 4
+     * bytes), and a StringBuilder in the charset of the exchange.
+     */
+    private static Object asText(Object body) {
+        if (body instanceof CharSequence || body instanceof Number || body 
instanceof Boolean
+                || body instanceof Character || body instanceof Enum<?>) {
+            return body.toString();
+        }
+        return body;
+    }
+
     /**
      * The charset declared by the response Content-Type header, or null when 
there is no Content-Type header, it
      * declares no charset, or the charset is not supported.
diff --git 
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSingleValueResponseTest.java
 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSingleValueResponseTest.java
new file mode 100644
index 000000000000..fac3e6c9c32f
--- /dev/null
+++ 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSingleValueResponseTest.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.platform.http.vertx;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * CAMEL-26503: a number, a boolean, a character or an enum as the reply is 
written as its text, not in the binary form
+ * of the type converter (an Integer as 4 bytes).
+ */
+public class VertxPlatformHttpSingleValueResponseTest {
+
+    private CamelContext context;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        context = VertxPlatformHttpEngineTest.createCamelContext();
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("platform-http:/integer")
+                        .setBody(constant(42));
+
+                from("platform-http:/long")
+                        .setBody(constant(1234567890123L));
+
+                from("platform-http:/double")
+                        .setBody(constant(2.5d));
+
+                from("platform-http:/boolean")
+                        .setBody(constant(Boolean.TRUE));
+
+                from("platform-http:/character")
+                        .setBody(constant('x'));
+
+                from("platform-http:/enum")
+                        .setBody(constant(TimeUnit.SECONDS));
+
+                from("platform-http:/latin1")
+                        .setHeader(Exchange.CONTENT_TYPE, 
constant("text/plain; charset=ISO-8859-1"))
+                        .setBody(constant('ü'));
+
+                from("platform-http:/builder")
+                        .setHeader(Exchange.CONTENT_TYPE, 
constant("text/plain; charset=ISO-8859-1"))
+                        .process(exchange -> exchange.getMessage().setBody(new 
StringBuilder("Grüße")));
+            }
+        });
+        VertxPlatformHttpEngineTest.startCamelContext(context);
+    }
+
+    @AfterEach
+    void tearDown() {
+        context.stop();
+    }
+
+    @Test
+    void testIntegerReplyIsText() {
+        assertEquals("42", get("/integer"));
+    }
+
+    @Test
+    void testLongReplyIsText() {
+        assertEquals("1234567890123", get("/long"));
+    }
+
+    @Test
+    void testDoubleReplyIsText() {
+        assertEquals("2.5", get("/double"));
+    }
+
+    @Test
+    void testBooleanReplyIsText() {
+        assertEquals("true", get("/boolean"));
+    }
+
+    @Test
+    void testCharacterReplyIsText() {
+        assertEquals("x", get("/character"));
+    }
+
+    @Test
+    void testEnumReplyIsText() {
+        assertEquals("SECONDS", get("/enum"));
+    }
+
+    @Test
+    void testCharacterReplyInDeclaredCharset() {
+        byte[] body = given()
+                .get("/latin1")
+                .then()
+                .statusCode(200)
+                .extract().asByteArray();
+
+        assertArrayEquals("ü".getBytes(StandardCharsets.ISO_8859_1), body);
+    }
+
+    @Test
+    void testStringBuilderReplyInDeclaredCharset() {
+        byte[] body = given()
+                .get("/builder")
+                .then()
+                .statusCode(200)
+                .extract().asByteArray();
+
+        assertArrayEquals("Grüße".getBytes(StandardCharsets.ISO_8859_1), body);
+    }
+
+    private static String get(String path) {
+        byte[] body = given()
+                .get(path)
+                .then()
+                .statusCode(200)
+                .extract().asByteArray();
+        return new String(body, StandardCharsets.UTF_8);
+    }
+}
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 2e58a5d51433..d31cef6f66d7 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -2410,6 +2410,15 @@ ISO-8859-1 and `CamelCharsetName` is set. Before, only 
`charset=` in lower case
 as UTF-8. An empty charset parameter (`charset=` or `charset=""`) now counts 
as no charset, as in camel-undertow,
 camel-netty-http and camel-http-common (CAMEL-25355); before, converting the 
body to a String failed with 500.
 
+=== camel-platform-http-vertx - a number, a boolean, a character or an enum 
reply is written as text
+
+A reply body that is a number, a boolean, a character or an enum is now 
written as its text, in the charset of the
+response `Content-Type` (UTF-8 otherwise), as camel-undertow does: 
`setBody(constant(42))` replies with `42`. Before,
+an `Integer`, `Long`, `Short`, `Float` or `Double` was written in its binary 
form (`42` became the 4 bytes
+`00 00 00 2A`), and a boolean, a character or an enum failed with 500. A 
`StringBuilder` or another `CharSequence` is
+now also written in the charset of the response `Content-Type`, as a `String` 
is, rather than in the charset of the
+exchange. To send the binary form of a number, convert the body to `byte[]` 
first.
+
 === camel-report-maven-plugin - Java routes are read with the Java DSL parser
 
 The `validate` and `route-coverage` goals read Java routes with the Java DSL 
parser of camel-java-io instead of

Reply via email to