Servlet Component

The servlet: component provides HTTP based endpoints for consuming HTTP requests that arrive at a HTTP endpoint and this endpoint is bound to a published Servlet.

Note: This component is new to Camel 2.0-M3.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-servlet</artifactId>
    <version>x.x.x</version>
    <\!-\- use the same version as your Camel core version \-->
</dependency>

URI format

servlet://relative_path[?options]

You can append query options to the URI in the following format, ?option=value&option=value&...

Options

Name Default Value Description
httpBindingRef null Reference to an org.apache.camel.component.http.HttpBinding in the Registry. A HttpBinding implementation can be used to customize how to write a response.
matchOnUriPrefix false Whether or not the CamelServlet should try to find a target consumer by matching the URI prefix, if no exact match is found.
servletName null Specifies the servlet name that the servlet endpoint will bind to. If there is no servlet name specified, the servlet endpoint will be bind to first published Servlet

Message Headers

Camel will apply the same Message Headers as the HTTP component.

Camel will also populate all request.parameter and request.headers. For example, if a client request has the URL, http://myserver/myserver?orderid=123, the exchange will contain a header named orderid with the value 123.

Usage

You can only consume from endpoints generated by the Servlet component. Therefore, it should only be used as input into your camel routes. To issue HTTP requests against other HTTP endpoints, use the HTTP Component

Sample

In this sample, we define a route that exposes a HTTP service at http://localhost:8080/camel/services/hello.
First, you need to publish the CamelHttpTransportServlet through the normal Web Container, or OSGi Service.
Use the Web.xml file to publish the CamelHttpTransportServlet as follows:

<web-app>

  <servlet>
    <servlet-name>CamelServlet</servlet-name>
    <display-name>Camel Http Transport Servlet</display-name>
    <servlet-class>
        org.apache.camel.component.servlet.CamelHttpTransportServlet
    </servlet-class>
    
  </servlet>

  <servlet-mapping>
    <servlet-name>CamelServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>

</web-app>

Use an Activator to publish the CamelHttpTransportServlet on the OSGi platform

import java.util.Dictionary;
import java.util.Hashtable;

import javax.servlet.Servlet;

import org.apache.camel.component.servlet.CamelHttpTransportServlet;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;

public final class ServletActivator implements BundleActivator {
    
    /**
     * HttpService reference.
     */
    private ServiceReference httpServiceRef;

    /**
     * Called when the OSGi framework starts our bundle
     */
    @SuppressWarnings("unchecked")
    public void start(BundleContext bc) throws Exception {
        httpServiceRef = bc.getServiceReference(HttpService.class.getName());
        if (httpServiceRef != null) {
            final HttpService httpService = (HttpService)bc.getService(httpServiceRef);
            if (httpService != null) {
                // create a default context to share between registrations
                final HttpContext httpContext = httpService.createDefaultHttpContext();
                // register the hello world servlet
                final Dictionary initParams = new Hashtable();
                initParams.put("matchOnUriPrefix", "false");
                initParams.put("servlet-name", "camelServlet");
                httpService.registerServlet("/camel/services", // alias
                    (Servlet)new CamelHttpTransportServlet(), // register servlet
                    initParams, // init params
                    httpContext // http context
                );

            }
        }
    }

    /**
     * Called when the OSGi framework stops our bundle
     */
    public void stop(BundleContext bc) throws Exception {
        if (httpServiceRef != null) {
            bc.ungetService(httpServiceRef);
            httpServiceRef = null;
        }
    }

}

Then you can define your route as follows:

from("servlet:///hello?matchOnUriPrefix=true").process(new Processor() {
    public void process(Exchange exchange) throws Exception {
        String contentType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class);
        String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
        assertEquals("Get a wrong content type", CONTENT_TYPE, contentType);
        String charsetEncoding = exchange.getIn().getHeader(Exchange.HTTP_CHARACTER_ENCODING, String.class);
        assertEquals("Get a wrong charset name", "UTF-8", charsetEncoding);
        exchange.getOut().setHeader(Exchange.CONTENT_TYPE, contentType + "; charset=UTF-8");                        
        exchange.getOut().setHeader("PATH", path);
        exchange.getOut().setBody("<b>Hello World</b>");
    }
});
Specify the relative path for camel-servlet endpoint

Since we are binding the Http transport with a published servlet, and we don't know the servlet's application context path, the camel-servlet endpoint uses the relative path to specify the endpoint's URL. A client can access the camel-servlet endpoint through the servlet publish address: ("http://localhost:8080/camel/services") + RELATIVE_PATH("/hello").

See Also

Graphic Design By Hiram