This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch jc2 in repository https://gitbox.apache.org/repos/asf/camel.git
commit ff83c2e26fb0a292052b4659a72fc91e4caa5163 Author: Claus Ibsen <[email protected]> AuthorDate: Tue Mar 10 11:23:14 2026 +0100 CAMEL-23160: camel-core - Add type converter for camel-util-json --- .../camel/impl/engine/DefaultClassResolver.java | 11 ++++++ .../camel/converter/json/JsonConverterTest.java | 42 ++++++++++++++++++++++ .../apache/camel/language/simple/SimpleTest.java | 36 +++++++++++++++++++ .../stream/CamelSupportBulkConverterLoader.java | 11 +++++- .../apache/camel/converter/json/JsonConverter.java | 6 ++++ 5 files changed, 105 insertions(+), 1 deletion(-) diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultClassResolver.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultClassResolver.java index 385294c5d235..23df173ffed6 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultClassResolver.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultClassResolver.java @@ -21,6 +21,7 @@ import java.net.URL; import java.util.Collections; import java.util.Enumeration; import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; import org.apache.camel.CamelContext; @@ -34,6 +35,12 @@ import org.apache.camel.util.ObjectHelper; */ public class DefaultClassResolver implements ClassResolver, CamelContextAware { + // shorthand for known camel types (so you do not have to remember to FQN) + private static final Map<String, String> KNOWN_CAMEL_TYPES = Map.of( + "JsonObject", "org.apache.camel.util.json.JsonObject", + "JsonArray", "org.apache.camel.util.json.JsonArray", + "Json", "org.apache.camel.util.json.Jsonable"); + private Set<ClassLoader> classLoaders; private CamelContext camelContext; @@ -100,6 +107,10 @@ public class DefaultClassResolver implements ClassResolver, CamelContextAware { // fallback and use application context class loader answer = loadClass(name, getApplicationContextClassLoader()); } + if (answer == null && KNOWN_CAMEL_TYPES.containsKey(name)) { + // try alias + answer = resolveClass(KNOWN_CAMEL_TYPES.get(name)); + } return answer; } diff --git a/core/camel-core/src/test/java/org/apache/camel/converter/json/JsonConverterTest.java b/core/camel-core/src/test/java/org/apache/camel/converter/json/JsonConverterTest.java index 6bc743e268b9..627b18a2036a 100644 --- a/core/camel-core/src/test/java/org/apache/camel/converter/json/JsonConverterTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/converter/json/JsonConverterTest.java @@ -17,6 +17,9 @@ package org.apache.camel.converter.json; import org.apache.camel.ContextTestSupport; +import org.apache.camel.model.ConvertBodyDefinition; +import org.apache.camel.model.FromDefinition; +import org.apache.camel.model.RouteDefinition; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; import org.junit.jupiter.api.Assertions; @@ -96,4 +99,43 @@ public class JsonConverterTest extends ContextTestSupport { Assertions.assertEquals(1949, b2.getInteger("year")); } + @Test + public void testConvertObjectShorthand() throws Exception { + RouteDefinition rd = new RouteDefinition(); + rd.setInput(new FromDefinition("direct:start")); + rd.addOutput(new ConvertBodyDefinition("JsonObject")); // use shorthand name instead of full FQN + context.addRouteDefinition(rd); + + JsonObject jo = (JsonObject) template.requestBody("direct:start", BOOKS); + Assertions.assertNotNull(jo); + + JsonArray arr = jo.getJsonObject("library").getJsonArray("book"); + Assertions.assertEquals(2, arr.size()); + JsonObject b1 = arr.getJsonObject(0); + JsonObject b2 = arr.getJsonObject(1); + Assertions.assertEquals("No Title", b1.getString("title")); + Assertions.assertEquals(1925, b1.getInteger("year")); + Assertions.assertEquals("1984", b2.getString("title")); + Assertions.assertEquals(1949, b2.getInteger("year")); + } + + @Test + public void testConvertArrayShorthand() throws Exception { + RouteDefinition rd = new RouteDefinition(); + rd.setInput(new FromDefinition("direct:start")); + rd.addOutput(new ConvertBodyDefinition("JsonArray")); // use shorthand name instead of full FQN + context.addRouteDefinition(rd); + + JsonArray arr = (JsonArray) template.requestBody("direct:start", BOOKS_ARR); + Assertions.assertNotNull(arr); + + Assertions.assertEquals(2, arr.size()); + JsonObject b1 = arr.getJsonObject(0); + JsonObject b2 = arr.getJsonObject(1); + Assertions.assertEquals("No Title", b1.getString("title")); + Assertions.assertEquals(1925, b1.getInteger("year")); + Assertions.assertEquals("1984", b2.getString("title")); + Assertions.assertEquals(1949, b2.getInteger("year")); + } + } diff --git a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java index de65f6475292..042579a3dfa7 100644 --- a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java @@ -60,6 +60,8 @@ import org.apache.camel.support.ExchangeHelper; import org.apache.camel.support.LanguageHelper; import org.apache.camel.util.InetAddressUtil; import org.apache.camel.util.StringHelper; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; import org.apache.camel.util.json.Jsoner; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.ResourceLock; @@ -2712,6 +2714,40 @@ public class SimpleTest extends LanguageTestSupport { assertEquals(Boolean.TRUE, s); } + @Test + public void testConvertToCamelJson() { + exchange.getMessage().setBody("{ \"name\": \"Scott\", \"age\": 44 }"); + + Expression expression = context.resolveLanguage("simple").createExpression("${convertTo(JsonObject)}"); + JsonObject jo = expression.evaluate(exchange, JsonObject.class); + assertNotNull(jo); + assertEquals("Scott", jo.getString("name")); + assertEquals(44, jo.getInteger("age")); + + // shorthand for either JSonObject or JSonArray + expression = context.resolveLanguage("simple").createExpression("${convertTo(Json)}"); + jo = expression.evaluate(exchange, JsonObject.class); + assertNotNull(jo); + assertEquals("Scott", jo.getString("name")); + assertEquals(44, jo.getInteger("age")); + + exchange.getMessage().setBody("[ { \"name\": \"Scott\", \"age\": 44 }, { \"name\": \"Jack\", \"age\": 23 } ]"); + expression = context.resolveLanguage("simple").createExpression("${convertTo(JsonArray)}"); + JsonArray arr = expression.evaluate(exchange, JsonArray.class); + assertNotNull(arr); + assertEquals(2, arr.size()); + assertEquals("Scott", arr.getJsonObject(0).getString("name")); + assertEquals(44, arr.getJsonObject(0).getInteger("age")); + assertEquals("Jack", arr.getJsonObject(1).getString("name")); + assertEquals(23, arr.getJsonObject(1).getInteger("age")); + + // shorthand for either JSonObject or JSonArray + expression = context.resolveLanguage("simple").createExpression("${convertTo(Json)}"); + arr = expression.evaluate(exchange, JsonArray.class); + assertNotNull(arr); + assertEquals(2, arr.size()); + } + @Test public void testConvertToOGNL() { exchange.getIn().setBody(new OrderLine(123, "Camel in Action")); diff --git a/core/camel-support/src/generated/java/org/apache/camel/converter/stream/CamelSupportBulkConverterLoader.java b/core/camel-support/src/generated/java/org/apache/camel/converter/stream/CamelSupportBulkConverterLoader.java index 7a7a1177fc87..ee06fd855ade 100644 --- a/core/camel-support/src/generated/java/org/apache/camel/converter/stream/CamelSupportBulkConverterLoader.java +++ b/core/camel-support/src/generated/java/org/apache/camel/converter/stream/CamelSupportBulkConverterLoader.java @@ -41,7 +41,7 @@ public final class CamelSupportBulkConverterLoader implements TypeConverterLoade @Override public int size() { - return 8; + return 9; } @Override @@ -92,6 +92,10 @@ public final class CamelSupportBulkConverterLoader implements TypeConverterLoade if (value instanceof java.lang.String) { return org.apache.camel.converter.json.JsonConverter.convertToJsonObject((java.lang.String) value, exchange); } + } else if (to == org.apache.camel.util.json.Jsonable.class) { + if (value instanceof java.lang.String) { + return org.apache.camel.converter.json.JsonConverter.convertToJson((java.lang.String) value, exchange); + } } return null; } @@ -105,6 +109,7 @@ public final class CamelSupportBulkConverterLoader implements TypeConverterLoade registry.addConverter(new TypeConvertible<>(java.io.Reader.class, org.apache.camel.StreamCache.class), this); registry.addConverter(new TypeConvertible<>(java.lang.String.class, org.apache.camel.util.json.JsonArray.class), this); registry.addConverter(new TypeConvertible<>(java.lang.String.class, org.apache.camel.util.json.JsonObject.class), this); + registry.addConverter(new TypeConvertible<>(java.lang.String.class, org.apache.camel.util.json.Jsonable.class), this); } public TypeConverter lookup(Class<?> to, Class<?> from) { @@ -137,6 +142,10 @@ public final class CamelSupportBulkConverterLoader implements TypeConverterLoade if (from == java.lang.String.class) { return this; } + } else if (to == org.apache.camel.util.json.Jsonable.class) { + if (from == java.lang.String.class) { + return this; + } } return null; } diff --git a/core/camel-support/src/main/java/org/apache/camel/converter/json/JsonConverter.java b/core/camel-support/src/main/java/org/apache/camel/converter/json/JsonConverter.java index 15b4d75cd1f3..d522a5f791e7 100644 --- a/core/camel-support/src/main/java/org/apache/camel/converter/json/JsonConverter.java +++ b/core/camel-support/src/main/java/org/apache/camel/converter/json/JsonConverter.java @@ -20,6 +20,7 @@ import org.apache.camel.Converter; import org.apache.camel.Exchange; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; +import org.apache.camel.util.json.Jsonable; import org.apache.camel.util.json.Jsoner; /** @@ -44,4 +45,9 @@ public final class JsonConverter { return (JsonArray) Jsoner.deserialize(json); } + @Converter(order = 3) + public static Jsonable convertToJson(String json, Exchange exchange) throws Exception { + return (Jsonable) Jsoner.deserialize(json); + } + }
