h2. ServletListener Component
*Available as of Camel 2.11*
This component is used for bootstrapping Camel applications in web applications. For example beforehand people would have to find their own way of bootstrapping Camel, or rely on 3rd party frameworks such as Spring to do it.
There may be situations where you want a pure Camel based solution, without the extra overhead of Spring Framework.
{note:title=Sidebar}
This component works as a {{javax.servlet.ServletContextListener}}, which works in any web container of today, as well any older containers.
There may be solutions around the corner which is based on Servlet 3.x and annotation driven configuration, or using [CDI] or other means.
This component is old school and based on the pure API from Servlet 2.x, which means it works in any web container. Also the old ones, which was the goal.
{note}
Maven users will need to add the following dependency to their {{pom.xml}} for this component:
{code:xml}
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-servletlistener</artifactId>
<version>x.x.x</version>
<\!-\- use the same version as your Camel core version \-->
</dependency>
{code}
h3. Using
To use this you need to configure the {{org.apache.camel.component.servletlistener.CamelServletContextListener}} in the {{WEB-INF/web.xml}} file as shown below:
{snippet:id=web|lang=xml|url=camel/trunk/components/camel-servletlistener/src/test/resources/myweb.xml}
h3. Options
The {{org.apache.camel.component.servletlistener.CamelServletContextListener}} supports the following options which can be configured as context-param in the web.xml file.
{div:class=confluenceTableSmall}
|| Option || Type || Description ||
| propertyPlaceholder.XXX | | To configure [property placeholders|Using PropertyPlaceholder] in Camel. You should prefix the option with "propertyPlaceholder.", for example to configure the location, use propertyPlaceholder.location as name. You can configure all the options from the [Properties] component. |
| jmx.XXX | | To configure [JMX|Camel JMX]. You should prefix the option with "jmx.", for example to disable JMX, use jmx.disabled as name. You can configure all the options from {{org.apache.camel.spi.ManagementAgent}}. As well the options mentioned on the [JMX|Camel JMX] page. |
| name | {{String}} | To configure the name of the [CamelContext]. |
| streamCache | {{Boolean}} | Whether to enable [Stream Caching]. |
| trace | {{Boolean}} | Whether to enable [Tracer]. |
| delayer | {{Long}} | To set a delay value for [Delay Interceptor]. |
| handleFault | {{Boolean}} | Whether to enable handle fault. |
| errorHandlerRef | {{String}} | Refers to a context scoped [Error Handler] to be used. |
| autoStartup | {{Boolean}} | Whether to start all routes when starting Camel. |
| useMDCLogging | {{Boolean}} | Whether to use [MDC Logging]. |
| useBreadcrumb | {{Boolean}} | Whether to use [breadcrumb|MDC Logging]. |
| managementNamePattern | {{String}} | To set a custom naming pattern for JMX MBeans. |
| threadNamePattern | {{String}} | To set a custom naming pattern for threads. |
| properties.XXX | | To set custom properties on {{CamelContext.getProperties}}. This is seldom in use. |
| routebuilder.XXX | | To configure routes to be used. See below for more details. |
| CamelContextLifecycle | | Refers to a FQN classname of an implementation of {{org.apache.camel.component.servletlistener.CamelContextLifecycle}}. Which allows to execute custom code before and after [CamelContext] has been started or stopped. See below for further details. |
| XXX | | To set any option on [CamelContext]. |
{div}
h3. Examples
See [Servlet Tomcat No Spring Example].
h3. Configuring routes
You need to configure which routes to use in the web.xml file. You can do this in a number of ways, though all the parameters must be prefixed with "routeBuilder".
h4. Using a RouteBuilder class
By default Camel will assume the param-value is a FQN classname for a Camel [RouteBuilder] class, as shown below:
{code:xml}
<context-param>
<param-name>routeBuilder-MyRoute</param-name>
<param-value>org.apache.camel.component.servletlistener.MyRoute</param-value>
</context-param>
{code}
You can specify multiple classes in the same param-value as shown below:
{code:xml}
<context-param>
<param-name>routeBuilder-routes</param-name>
<!-- we can define multiple values separated by comma -->
<param-value>
org.apache.camel.component.servletlistener.MyRoute,
org.apache.camel.component.servletlistener.routes.BarRouteBuilder
</param-value>
</context-param>
{code}
The name of the parameter does not have a meaning at runtime. It just need to be unique and start with "routeBuilder". In the example above we have "routeBuilder-routes". But you could just as well have named it "routeBuilder.foo".
h4. Using package scanning
You can also tell Camel to use package scanning, which mean it will look in the given package for all classes of [RouteBuilder] types and automatic adding them as Camel routes. To do that you need to prefix the value with "packagescan:" as shown below:
{code:xml}
<context-param>
<param-name>routeBuilder-MyRoute</param-name>
<!-- define the routes using package scanning by prefixing with packagescan: -->
<param-value>packagescan:org.apache.camel.component.servletlistener.routes</param-value>
</context-param>
{code}
h4. Using a XML file
You can also define Camel routes using XML DSL, though as we are not using Spring or Blueprint the XML file can only contain Camel route(s).
In the web.xml you refer to the XML file which can be from "classpath", "file" or a "http" url, as shown below:
{code:xml}
<context-param>
<param-name>routeBuilder-MyRoute</param-name>
<param-value>classpath:routes/myRoutes.xml</param-value>
</context-param>
{code}
And the XML file is:
{code:xml:title=routes/myRoutes.xml}
<?xml version="1.0" encoding="UTF-8"?>
<!-- the xmlns="http://camel.apache.org/schema/spring" is needed -->
<routes xmlns="http://camel.apache.org/schema/spring">
<route id="foo">
<from uri="direct:foo"/>
<to uri="mock:foo"/>
</route>
<route id="bar">
<from uri="direct:bar"/>
<to uri="mock:bar"/>
</route>
</routes>
{code}
Notice that in the XML file the root tag is <routes> which must use the namespace "http://camel.apache.org/schema/spring". This namespace is having the spring in the name, but that is because of historical reasons, as Spring was the first and only XML DSL back in the time. At runtime no Spring JARs is needed. Maybe in Camel 3.0 the namespace can be renamed to a generic name.
h4. Configuring propert placeholders
Here is a snippet of a web.xml configuration for setting up property placeholders to load {{myproperties.properties}} from the classpath
{code:xml}
<!-- setup property placeholder to load properties from classpath -->
<!-- we do this by setting the param-name with propertyPlaceholder. as prefix and then any options such as location, cache etc -->
<context-param>
<param-name>propertyPlaceholder.location</param-name>
<param-value>classpath:myproperties.properties</param-value>
</context-param>
<!-- for example to disable cache on properties component, you do -->
<context-param>
<param-name>propertyPlaceholder.cache</param-name>
<param-value>false</param-value>
</context-param>
{code}
h4. Configuring JMX
Here is a snippet of a web.xml configuration for configuring JMX, such as disabling JMX.
{code:xml}
<!-- configure JMX by using names that is prefixed with jmx. -->
<!-- in this example we disable JMX -->
<context-param>
<param-name>jmx.disabled</param-name>
<param-value>true</param-value>
</context-param>
{code}
h3. JNDI and Camel [Registry]
This component uses JNDI/{{javax.naming.Context}} using the {{org.apache.camel.util.jndi.JndiContext}} as the [Registry] implementation.
This allows you to lookup [Bean]s and other services in JNDI, and as well to bind and unbind your own [Bean]s.
This is done from Java code by implementing the {{org.apache.camel.component.servletlistener.CamelContextLifecycle}}. There is a base class {{org.apache.camel.component.servletlistener.CamelContextLifecycleSupport}} which is easier to extend, than implementing the interface.
h4. Using custom CamelContextLifecycleSupport
In the code below we use the callbacks {{beforeStart}} and {{afterStop}} to enlist our custom bean in the JNDI [Registry], and as well to cleanup when we stop.
{snippet:id=e1|lang=java|url=camel/trunk/components/camel-servletlistener/src/test/java/org/apache/camel/component/servletlistener/MyLifecycle.java}
Then we need to register this class in the web.xml file as shown below, using the parameter name "CamelContextLifecycle". The value must be a FQN which refers to the class implementing the {{org.apache.camel.component.servletlistener.CamelContextLifecycleSupport}} interface.
{code:xml}
<context-param>
<param-name>CamelContextLifecycle</param-name>
<param-value>org.apache.camel.component.servletlistener.MyLifecycle</param-value>
</context-param>
{code}
As we enlisted our HelloBean [Bean] using the name "myBean" we can refer to this [Bean] in the Camel routes as shown below:
{code}
public class MyBeanRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
from("seda:foo").routeId("foo")
.to("bean:myBean")
.to("mock:foo");
}
}
{code}
{tip}
In the CamelContextLifecycleSupport implementation you can of course do any kind of code in the callback methods. There is 4 callbacks for before/after starting [CamelContext], and as well for before/after stopping as well.
{tip}
h3. See Also
- [Servlet]
- [Servlet Tomcat Example]
- [Servlet Tomcat No Spring Example] |