Chapter 5. XML IO DSL


The xml-io-dsl is the Camel optimized XML DSL with a very fast and low overhead XML parser. It is a source code generated parser that is Camel specific and can only parse Camel .xml route files (not classic Spring <beans> XML files).

We recommend that you use xml-io-dsl instead of xml-jaxb-dsl for Camel XML DSL. It works with all Camel runtimes.

Note

When you are using XML IO DSL, the camel-spring-boot application will by default look for xml files in src/main/resources/camel/*.xml.

You can configure this behavior by providing a different path in the camel.springboot.routes-include-pattern property:

camel.springboot.routes-include-pattern=/path/to/*.xml

5.1. Example

The following my-route.xml source file can be loaded and run with Camel CLI or Camel K:

my-route.xml

<routes xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="timer:tick"/>
        <setBody>
            <constant>Hello Camel K!</constant>
         </setBody>
        <to uri="log:info"/>
    </route>
</routes>

Tip

You can omit the xmlns namespace.

If there is only a single route, you can use <route> as the root XML tag instead of <routes>.

Running with Camel K

kamel run my-route.xml

Running with Camel CLI

camel run my-route.xml

You can use xml-io-dsl to declare some beans to be bound to the Camel Registry.

You can declare and Beans define their properties (including nested properties) in XML. For example:

Bean declaration and definition

<camel>

	<bean name="beanFromProps" type="com.acme.MyBean">
		<properties>
			<property key="field1" value="f1_p" />
			<property key="field2" value="f2_p" />
			<property key="nested.field1" value="nf1_p" />
			<property key="nested.field2" value="nf2_p" />
		</properties>
	</bean>

</camel>

While keeping all the benefits of fast XML parser used by xml-io-dsl, Camel can also process XML elements declared in other XML namespaces and process them separately. With this mechanism it is possible to include XML elements using Spring’s http://www.springframework.org/schema/beans namespace.

This brings the flexibility of Spring Beans into Camel main without actually running any Spring Application Context (or Spring Boot).

When elements from Spring namespace are found, they are used to populate and configure an instance of org.springframework.beans.factory.support.DefaultListableBeanFactory and leverage Spring dependency injection to wire the beans together.

These beans are then exposed through normal Camel Registry and may be used by Camel routes.

Here’s an example camel.xml file, which defines both the routes and beans used (referred to) by the route definition:

camel.xml

<camel>

    <beans xmlns="http://www.springframework.org/schema/beans">
        <bean id="messageString" class="java.lang.String">
            <constructor-arg index="0" value="Hello"/>
        </bean>

        <bean id="greeter" class="org.apache.camel.main.app.Greeter">
            <description>Spring Bean</description>
            <property name="message">
                <bean class="org.apache.camel.main.app.GreeterMessage">
                    <property name="msg" ref="messageString"/>
                </bean>
            </property>
        </bean>
    </beans>

    <route id="my-route">
        <from uri="direct:start"/>
        <bean ref="greeter"/>
        <to uri="mock:finish"/>
    </route>

</camel>

A my-route route is referring to greeter bean which is defined using Spring <bean> element.

More examples can be found on the Apache Camel JBang page.

5.2. Using beans with constructors

When you want to create beans with constructor arguments, from Camel 4.1 onwards you can add them as XML tags. For example:

Camel 4.1+: Beans with constructor tags

<camel>

	<bean name="beanFromProps" type="com.acme.MyBean">
        <constructors>
          <constructor index="0" value="true"/>
          <constructor index="1" value="Hello World"/>
        </constructors>
        <!-- and you can still have properties -->
		<properties>
			<property key="field1" value="f1_p" />
			<property key="field2" value="f2_p" />
			<property key="nested.field1" value="nf1_p" />
			<property key="nested.field2" value="nf2_p" />
		</properties>
	</bean>

</camel>

If you use Camel 4.0, you must put then constructor arguments in the type attribute:

Camel 4.0: Beans with constructor arguments in the type attribute

<bean name="beanFromProps" type="com.acme.MyBean(true, 'Hello World')">
    <properties>
        <property key="field1" value="f1_p" />
        <property key="field2" value="f2_p" />
        <property key="nested.field1" value="nf1_p" />
        <property key="nested.field2" value="nf2_p" />
    </properties>
</bean>

5.3. Creating beans from factory method

A bean can also be created from a public static factory method:

Factory method XML

	<bean name="myBean" type="com.acme.MyBean" factoryMethod="createMyBean">
        <constructors>
          <constructor index="0" value="true"/>
          <constructor index="1" value="Hello World"/>
        </constructors>
	</bean>

When you use a factoryMethod, you must provide constructor tags for the arguments.

For example, this means that the class com.acme.MyBean should be as follows:

Factory method

public class MyBean {

    public static MyBean createMyBean(boolean important, String message) {
        MyBean answer = ...
        // create and configure the bean
        return answer;
    }
}

Note

You must make the factory method public static in the created class.

5.4. Creating beans from builder classes

You can create a bean created from another builder class as shown below:

Builder XML

	<bean name="myBean" type="com.acme.MyBean"
          builderClass="com.acme.MyBeanBuilder" builderMethod="createMyBean">
        <properties>
          <property key="id" value="123"/>
          <property key="name" value="Acme"/>
        </constructors>
	</bean>

Note

You must make the builder class public with a no-arg default constructor.

You can then use the builder class to create the actual bean by using fluent builder style configuration.

Set the properties on the builder class, and create the bean by invoking the builderMethod at the end.

You invocate this method via Java reflection.

5.5. Creating beans from factory bean

You can create a bean from a factory bean as shown below:

Factory XML

	<bean name="myBean" type="com.acme.MyBean"
          factoryBean="com.acme.MyHelper" factoryMethod="createMyBean">
        <constructors>
          <constructor index="0" value="true"/>
          <constructor index="1" value="Hello World"/>
        </constructors>
	</bean>

Tip

You can also use factoryBean to refer to an existing bean by bean id instead of the FQN classname.

When you use a factoryBean the, you must provide arguments as constructor tags.

For example, the class com.acme.MyHelper should be as follows:

Factory bean

public class MyHelper {

    public static MyBean createMyBean(boolean important, String message) {
        MyBean answer = ...
        // create and configure the bean
        return answer;
    }
}

Note

You must make the factory method public static.

5.6. Creating beans using script language

If you have advanced use-cases, you can inline a script language, such as groovy, java, javascript, and so on, to create the bean.

With scripting, you can be more flexible and use a bit of programming to create and configure the bean:

Scripting

	<bean name="myBean" type="com.acme.MyBean" scriptLanguage="groovy">
        <script>
      // some groovy script here to create the bean
      bean = ...
      ...
      return bean
        </script>
	</bean>

Note

When you use script, the constructors, factory bean, and factory method are not used.

5.7. Using init and destroy methods on beans

If you need to do initialization and cleanup work before you use a bean, you can use the initMethod and destroyMethod which are triggered as appropriate by Camel.

Those methods must be public void and have no arguments, as shown below:

Initialization and cleanup methods

public class MyBean {

    public void initMe() {
        // do init work here
    }

    public void destroyMe() {
        // do cleanup work here
    }

}

You also have to declare those methods in the XML DSL as follows:

Initialization and cleanup XML

	<bean name="myBean" type="com.acme.MyBean"
          initMethod="initMe" destroyMethod="destroyMe">
        <constructors>
          <constructor index="0" value="true"/>
          <constructor index="1" value="Hello World"/>
        </constructors>
	</bean>

Both initMethod and destroyMethod are optional, so a bean does not have to have both.

5.8. REST and routes in the same XML IO DSL file

You can have both REST and routes in the same DSL file:

REST and routes in the same XML IO DSL file

<camel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://camel.apache.org/schema/spring"
       xsi:schemaLocation="
            http://camel.apache.org/schema/spring
            https://camel.apache.org/schema/spring/camel-spring.xsd">
   <rest id="rest">
        <post id="post" path="start">
            <to uri="direct:start"/>
        </post>
    </rest>

    <route>
        <from uri="direct:start"/>
        <to uri="amqp:queue:Test.Broker.StreamMessage?jmsMessageType=Stream&amp;disableReplyTo=true"/>
    </route>
</camel>

Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.