ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

What Is Jetty
Pages: 1, 2, 3, 4

Setting Up an Embedded Container: The Jetty API

Hopefully those ideas whet your appetite to try an embedded servlet container. The sample program Step1Driver demonstrates a simple Jetty-based service. It instantiates a servlet container, maps a servlet class to a Uniform Resource Identifier (URI), and invokes some URL calls against itself. I have sacrificed production quality for legibility.



The Service object is the Jetty container itself. Instantiating such an object brings the container into existence:

Server service = new Server() ;

Thus far, the Service object is akin to a hotel with no doors: no one can get in to use it, so it's of little value. The following line of code sets up the container to listen on the localhost interface, port 7501.

service.addListener( "localhost:7501" ) ;

To listen on all available interfaces, omit the hostname ("addListener( ":7501" )"). As its name would imply, you can call addListener() multiple times to listen on different interfaces.

Notice that the sample code maintains a reference to the Server object. This is required to shutdown the container later on.

Mapping web applications to the Service is straightforward:

service.addWebApplication(
   "/someContextPath" ,
   "/path/to/some.war"
) ;

This call will process a web app's web.xml deployment descriptor to map its filters and servlets, the same as any other container. The first argument is the name of the context path. All of this web app's servlets and JSPs will be available at URIs relative to this path. The second argument is the web app itself. This can be either a packed WAR file or a web app in exploded-directory format. Call addWebApplication() again to map more web apps.

Note that Jetty doesn't require a full-blown, spec-compliant WAR file to deploy servlets, either. If you have written a custom application protocol that rides HTTP, you can load a single servlet that exposes your app to the network. There's no need to WAR up your otherwise non-web app just for the sake of HTTP-enabling it.

To map such a one-off servlet, create a context on the fly by calling getContext() on the Service object. The sample code does just this to create a context called /embed:

ServletHttpContext ctx = (ServletHttpContext)
   service.getContext( "/embed" ) ;

The call to getContext() creates the context if it doesn't already exist.

Next, call addServlet() to map the servlet class to a URI:

ctx.addServlet(
   "Simple" , // servlet name
   "/TryThis/*" , // URI mapping pattern
   "sample.SimpleServlet" // class name
) ;

The first parameter is a descriptive name for the servlet. The second is the mapped path, equivalent to the <url-pattern> in a web.xml servlet mapping. This mapped path is relative to the context path, here /embed. The "/*" fragment means that this servlet will accept calls for /embed/TryThis as well as anything that begins with that URI, such as /embed/TryThis/123. This mapping style is useful when you have a single servlet that acts as an entry point to a greater system. Struts and Axis are examples of real-world apps that use such a servlet mapping.

Sometimes you want your context to be the root, or "/," to better mimic plain HTTP services. Jetty supports this via the Service.setRootWebapp() method:

service.setRootWebapp(
   "/path/to/another.war"
) ;

The only argument is the path to a web app (WAR or directory).

The container is idle at this point. It hasn't even attempted to bind to its listener socket. Starting the container requires a single call:

service.start() ;

This method returns immediately because Jetty takes care of running the service in a separate thread. main() is free to do whatever it likes while the container keeps running.

The remainder of the code is a set of URL calls to the embedded container. These calls confirm that the container is indeed running and that the servlet functions as expected.

Stopping the container is as straightforward as starting it:

service.stop() ;

Note the catch() clause of the outer try/catch block:

{

   service.start() ;
   // ... URL calls to mapped servlet ...
   service.stop() ;

}catch( Throwable t ){

   System.exit( 1 ) ;

}

The explicit call to System.exit() ensures the container is shutdown in the event of an exception. The container would otherwise continue to run in its own thread and the app would never exit.

Keep in mind that Jetty web apps aren't limited to in-code access. Were I to remove the call to service.stop() the container would run indefinitely and I could invoke the servlet via a browser. For example:

http://localhost:7501/embed/TryThis/SomeExtraInfo

You don't have to take my word for it. The sample code is suitable for running as an Eclipse project. There is also a shell script for running the code from a Unix/Linux command line. In both cases, be sure to adjust the classpath to point to your Jetty install location.

Pages: 1, 2, 3, 4

Next Pagearrow