{"id":2084,"date":"2026-02-01T00:44:54","date_gmt":"2026-01-31T11:44:54","guid":{"rendered":"https:\/\/www.ronella.xyz\/?p=2084"},"modified":"2026-02-01T00:44:54","modified_gmt":"2026-01-31T11:44:54","slug":"apache-camel-transformer","status":"publish","type":"post","link":"https:\/\/www.ronella.xyz\/?p=2084","title":{"rendered":"Apache Camel Transformer"},"content":{"rendered":"<p>Apache Camel's <strong>Transformer<\/strong> EIP enables declarative, type-safe message conversion between POJOs in routes. Below is a fully self-contained, single-file example using nested classes and Camel's <code>Main<\/code> class.<\/p>\n<h2>Complete Single-File Example<\/h2>\n<pre><code class=\"language-java\">import org.apache.camel.Message;\nimport org.apache.camel.builder.RouteBuilder;\nimport org.apache.camel.main.Main;\nimport org.apache.camel.spi.DataType;\nimport org.apache.camel.spi.Transformer;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n\/**\n * Apache Camel Transformer EIP example demonstrating declarative type-safe message conversion.\n * All classes (Lead, Customer, LeadToCustomerTransformer) are in this single file.\n *\/\npublic class TransformerDemo {\n    private static final Logger LOG = LoggerFactory.getLogger(TransformerDemo.class);\n\n    \/**\n     * Lead POJO - Input model\n     *\/\n    public static class Lead {\n        private String name;\n        private String company;\n        private String city;\n\n        public Lead() {}\n\n        public Lead(String name, String company, String city) {\n            this.name = name;\n            this.company = company;\n            this.city = city;\n        }\n\n        \/\/ Getters and setters\n        public String getName() { return name; }\n        public void setName(String name) { this.name = name; }\n        public String getCompany() { return company; }\n        public void setCompany(String company) { this.company = company; }\n        public String getCity() { return city; }\n        public void setCity(String city) { this.city = city; }\n\n        @Override\n        public String toString() {\n            return &quot;Lead{name=&#039;&quot; + name + &quot;&#039;, company=&#039;&quot; + company + &quot;&#039;, city=&#039;&quot; + city + &quot;&#039;}&quot;;\n        }\n    }\n\n    \/**\n     * Customer POJO - Output model\n     *\/\n    public static class Customer {\n        private String fullName;\n        private String organization;\n        private String location;\n\n        public Customer() {}\n\n        public Customer(String fullName, String organization, String location) {\n            this.fullName = fullName;\n            this.organization = organization;\n            this.location = location;\n        }\n\n        \/\/ Getters and setters\n        public String getFullName() { return fullName; }\n        public void setFullName(String fullName) { this.fullName = fullName; }\n        public String getOrganization() { return organization; }\n        public void setOrganization(String organization) { this.organization = organization; }\n        public String getLocation() { return location; }\n        public void setLocation(String location) { this.location = location; }\n\n        @Override\n        public String toString() {\n            return &quot;Customer{fullName=&#039;&quot; + fullName + &quot;&#039;, organization=&#039;&quot; + organization + &quot;&#039;, location=&#039;&quot; + location + &quot;&#039;}&quot;;\n        }\n    }\n\n    \/**\n     * Transformer implementation for converting Lead to Customer\n     *\/\n    public static class LeadToCustomerTransformer extends Transformer {\n        @Override\n        public void transform(Message message, DataType fromType, DataType toType) throws Exception {\n            Lead lead = message.getMandatoryBody(Lead.class);\n            Customer customer = new Customer(\n                lead.getName().toUpperCase(),\n                lead.getCompany(),\n                lead.getCity()\n            );\n            message.setBody(customer);\n        }\n    }\n\n    public static void main(String[] args) throws Exception {\n        Main main = new Main();\n        main.configure().addRoutesBuilder(new RouteBuilder() {\n            @Override\n            public void configure() {\n                \/\/ Register the transformer\n                transformer()\n                    .fromType(&quot;java:TransformerDemo$Lead&quot;)\n                    .toType(&quot;java:TransformerDemo$Customer&quot;)\n                    .withJava(LeadToCustomerTransformer.class);\n\n                \/\/ Main route with automatic transformation\n                from(&quot;direct:start&quot;)\n                    .inputType(&quot;java:TransformerDemo$Lead&quot;)\n                    .log(&quot;INPUT Lead: ${body}&quot;)\n                    .to(&quot;direct:process&quot;)  \/\/ Triggers transformer automatically\n                    .log(&quot;OUTPUT Customer: ${body}&quot;);\n\n                from(&quot;direct:process&quot;)\n                    .inputType(&quot;java:TransformerDemo$Customer&quot;)\n                    .log(&quot;PROCESSED Customer: ${body}&quot;)\n                    .to(&quot;log:final?showAll=true&quot;);\n            }\n        });\n\n        \/\/ Add a startup listener to send test message after Camel starts\n        main.addMainListener(new org.apache.camel.main.MainListenerSupport() {\n            @Override\n            public void afterStart(org.apache.camel.main.BaseMainSupport mainSupport) {\n                try {\n                    LOG.info(&quot;Sending test Lead message...&quot;);\n                    mainSupport.getCamelContext().createProducerTemplate()\n                        .sendBody(&quot;direct:start&quot;, new Lead(&quot;John Doe&quot;, &quot;Acme Corp&quot;, &quot;Auckland&quot;));\n                    LOG.info(&quot;Test message sent successfully!&quot;);\n                } catch (Exception e) {\n                    LOG.error(&quot;Failed to send test message&quot;, e);\n                }\n            }\n        });\n\n        \/\/ Run Camel (will run until Ctrl+C is pressed)\n        main.run(args);\n    }\n}<\/code><\/pre>\n<h2>Expected Console Output<\/h2>\n<pre><code>Sending test Lead message...\nINPUT Lead: Lead{name=&#039;John Doe&#039;, company=&#039;Acme Corp&#039;, city=&#039;Auckland&#039;}\nPROCESSED Customer: Customer{fullName=&#039;JOHN DOE&#039;, organization=&#039;Acme Corp&#039;, location=&#039;Auckland&#039;}\nExchange[Id: D0B1A9A95984A67-0000000000000000, RouteGroup: null, RouteId: route2, ExchangePattern: InOnly, Properties: {CamelToEndpoint=log:\/\/final?showAll=true}, Headers: {}, BodyType: TransformerDemo.Customer, Body: Customer{fullName=&#039;JOHN DOE&#039;, organization=&#039;Acme Corp&#039;, location=&#039;Auckland&#039;}]\nOUTPUT Customer: Customer{fullName=&#039;JOHN DOE&#039;, organization=&#039;Acme Corp&#039;, location=&#039;Auckland&#039;}\nTest message sent successfully!<\/code><\/pre>\n<h2>Key Implementation Details<\/h2>\n<p><strong>Nested Class References<\/strong>: Uses <code>TransformerDemo$Lead<\/code> syntax to reference nested classes in data type strings.<\/p>\n<p><strong>Transformer Method Signature<\/strong>: Uses <code>transform(Message message, DataType fromType, DataType toType)<\/code>\u2014the modern Camel 4.x+ API.<\/p>\n<p><strong>Automatic Startup Test<\/strong>: <code>MainListenerSupport.afterStart()<\/code> sends test message automatically when Camel context starts.<\/p>\n<p><strong>Single-File Design<\/strong>: All POJOs, transformer, and routes contained in one compilable <code>.java<\/code> file.<\/p>\n<h2>How the Transformation Triggers<\/h2>\n<ol>\n<li><strong>Input validation<\/strong> \u2192 <code>inputType(&quot;java:TransformerDemo$Lead&quot;)<\/code> expects Lead<\/li>\n<li><strong>Route boundary<\/strong> \u2192 <code>to(&quot;direct:process&quot;)<\/code> requires Customer input type<\/li>\n<li><strong>Type mismatch<\/strong> \u2192 Camel matches <code>Lead\u2192Customer<\/code> transformer automatically<\/li>\n<li><strong>Conversion executes<\/strong> \u2192 <code>LeadToCustomerTransformer.transform()<\/code> runs<\/li>\n<li><strong>Type contract satisfied<\/strong> \u2192 Route continues with Customer<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Apache Camel&#8217;s Transformer EIP enables declarative, type-safe message conversion between POJOs in routes. Below is a fully self-contained, single-file example using nested classes and Camel&#8217;s Main class. Complete Single-File Example import org.apache.camel.Message; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.main.Main; import org.apache.camel.spi.DataType; import org.apache.camel.spi.Transformer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; \/** * Apache Camel Transformer EIP example demonstrating declarative type-safe message [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[92],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/2084"}],"collection":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2084"}],"version-history":[{"count":1,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/2084\/revisions"}],"predecessor-version":[{"id":2085,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/2084\/revisions\/2085"}],"wp:attachment":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2084"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2084"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2084"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}