Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Jetty/Tutorial/Embedding Jetty"

 
(25 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
{{Jetty Tutorial
 
{{Jetty Tutorial
| introduction = Jetty has a slogan "Don't deploy your application in Jetty, deploy Jetty in your application". What this means is that as an alternative to bundling your application as a standard WAR to be deployed in Jetty, Jetty is designed to be a software component that can be instantiated and used in a Java program just like any [http://en.wikipedia.org/wiki/Plain_Old_Java_Object POJO].
+
| introduction =  
  
This tutorial takes you step-by-step from the simplest Jetty server instantiation, to running multiple web applications with standards-based deployment descriptors.
+
{{Jetty Redirect|http://www.eclipse.org/jetty/documentation/current/embedding-jetty.html}}
  
The [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/package-summary.html source] for most of these examples is part of the standard Jetty project.
+
Jetty has a slogan, "Don't deploy your application in Jetty, deploy Jetty in your application." What this means is that as an alternative to bundling your application as a standard WAR to be deployed in Jetty, Jetty is designed to be a software component that can be instantiated and used in a Java program just like any [http://en.wikipedia.org/wiki/Plain_Old_Java_Object POJO]. Put another way, running Jetty in embedded mode means putting an HTTP module into your application, rather than putting your application into an HTTP server.
 +
 
 +
This tutorial takes you step-by-step from the simplest Jetty server instantiation to running multiple web applications with standards-based deployment descriptors. The [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/package-summary.html source] for most of these examples is part of the standard Jetty project.
 +
 
 +
Before doing this tutorial, it is worth while to do the [[Jetty/Tutorial/Jetty HelloWorld|Hello World]] tutorial. This tutorial is also available as a [http://vimeo.com/19146453 Embedding Jetty Webinar recording].
 +
 
 +
{{Note|Jetty Version|The code in this tutorial is from Jetty 7, but should also work on Jetty 8. For the latest stable code, follow the links to the code xref from the latest release, which might vary slightly from the code examples given on this page.}}
  
 
| details =  
 
| details =  
Line 12: Line 18:
 
# Add/Configure Handlers
 
# Add/Configure Handlers
 
# Add/Configure Servlets/Webapps to Handlers
 
# Add/Configure Servlets/Webapps to Handlers
# start the server
+
# Start the server
# wait (join the server to prevent main exiting).
+
# Wait (join the server to prevent main exiting)
  
== Servers ==
+
== Creating a Server ==
The following code from [http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SimplestServer.java SimplestServer.java] will instantiate and run the simplest possible Jetty server:
+
The following code from [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/SimplestServer.html SimplestServer.java] instantiates and runs the simplest possible Jetty server:
 
<source lang="java">
 
<source lang="java">
 
public class SimplestServer
 
public class SimplestServer
Line 29: Line 35:
 
</source>
 
</source>
  
This runs a HTTP server on port 8080.  It is not a very useful server as it has no handlers and thus will return a 404 error for every request.
+
This runs an HTTP server on port 8080.  It is not a very useful server as it has no handlers and thus returns a 404 error for every request.
  
  
== Handlers ==
+
== Writing Handlers ==
In order to produce a response to a request, Jetty requires a [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/Handler.html Handler] to be set on the server.  A handler may:
+
To produce a response to a request, Jetty requires a [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/Handler.html Handler] to be set on the server.  A handler may:
* examine/modify the HTTP request.
+
* Examine/modify the HTTP request.
* generate the complete HTTP response.
+
* Generate the complete HTTP response.
* call another Handler (see [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerWrapper.html HandlerWrapper])
+
* Call another Handler (see [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerWrapper.html HandlerWrapper]).
* Select one or many Handlers to call (see [ http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerCollection.html HandlerCollection]
+
* Select one or many Handlers to call (see [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerCollection.html HandlerCollection]).
  
 
=== Hello World Handler ===
 
=== Hello World Handler ===
The following code based on [http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/HelloHandler.java HelloHandler.java] shows a simple hello world handler:
+
The following code based on [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/HelloHandler.html HelloHandler.java] shows a simple hello world handler:
 
<source lang="java">public class HelloHandler extends AbstractHandler
 
<source lang="java">public class HelloHandler extends AbstractHandler
 
{
 
{
Line 55: Line 61:
  
 
The parameters passed to the handle method are:
 
The parameters passed to the handle method are:
* target - The target of the request which is either a URI or a name from a named dispatcher.
+
* target–the target of the request, which is either a URI or a name from a named dispatcher.
* baseRequest -The Jetty mutable request object, which is always unwrapped.
+
* baseRequest–the Jetty mutable request object, which is always unwrapped.
* request - The immutable request object, which may have been wrapped.
+
* request–the immutable request object, which might have been wrapped.
* response - The response that may have been wrapped.
+
* response–the response, which might have been wrapped.
  
 
The handler sets the response status, content-type and marks the request as handled before it generates the body of the response using a writer.
 
The handler sets the response status, content-type and marks the request as handled before it generates the body of the response using a writer.
  
The following code from [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/OneHandler.html OneHandler.java] shows how this handler can be used by a Jetty server:
+
The following code from [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/OneHandler.html OneHandler.java] shows how a Jetty server can use this handler:
 
<source lang="java">
 
<source lang="java">
 
public static void main(String[] args) throws Exception
 
public static void main(String[] args) throws Exception
Line 74: Line 80:
 
</source>
 
</source>
  
You now know everything you need to know to write a HTTP server based on Jetty.  However, complex request handling is typically built from multiple Handlers and we will look in later sections how handlers can be combined like aspects. Some of the handlers available in Jetty can be seen in the [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/package-frame.html org.eclipse.jetty.server.handler] package.
+
You now know everything you need to know to write an HTTP server based on Jetty.  However, complex request handling is typically built from multiple Handlers. We will look in later sections at how you can combine handlers like aspects. You can see some of the handlers available in Jetty in the [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/package-frame.html org.eclipse.jetty.server.handler] package.
  
== Connectors ==
+
== Configuring Connectors ==
In order to configure the HTTP connectors used by the server, one or more [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/Connector.html Connector]s may be set on the server. Each connector may be configured with details such as interface, port, buffer sizes, timeouts etc.
+
To configure the HTTP connectors that the server uses, you can set one or more [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/Connector.html connector]s on the server. You can configure each connector with details such as interface, port, buffer sizes, timeouts, etc.
  
The following code is based on [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/ManyConnectors.html ManyConnectors.java] and shows how connectors may be set and configured for the Hello World example:
+
The following code is based on [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/ManyConnectors.html ManyConnectors.java] and shows how to set and configure connectors for the Hello World example:
 
<source lang="java">
 
<source lang="java">
 
public class ManyConnectors
 
public class ManyConnectors
Line 103: Line 109:
 
         System.setProperty("jetty.home",jetty_home);
 
         System.setProperty("jetty.home",jetty_home);
 
         ssl_connector.setPort(8443);
 
         ssl_connector.setPort(8443);
         ssl_connector.setKeystore(jetty_home + "/etc/keystore");
+
         SslContextFactory cf = ssl_connector.getSslContextFactory();
         ssl_connector.setPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
+
        cf.setKeyStore(jetty_home + "/etc/keystore");
         ssl_connector.setKeyPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
+
         cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
        server.addConnector(ssl_connector);
+
         cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
 
+
 
         server.setConnectors(new Connector[]{ connector0, connector1, ssl_connector });
 
         server.setConnectors(new Connector[]{ connector0, connector1, ssl_connector });
  
Line 118: Line 124:
 
</source>
 
</source>
  
== Handler Collections, Wrappers and Scopes ==
+
== Understanding Handler Collections, Wrappers and Scopes ==
  
 
Complex request handling is typically built from multiple Handlers that can be combined in various ways:
 
Complex request handling is typically built from multiple Handlers that can be combined in various ways:
* A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerCollection.html Handler Collection] holds a collection of other handlers and will call each handler in order. This is useful for combining statistics and logging handlers with the handler that generates the response.
+
* A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerCollection.html Handler Collection] holds a collection of other handlers and calls each handler in order. This is useful for combining statistics and logging handlers with the handler that generates the response.
 
* A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerList.html Handler List] is a Handler Collection that calls each handler in turn until either an exception is thrown, the response is committed or the request.isHandled() returns true. It can be used to combine handlers that conditionally handle a request.
 
* A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerList.html Handler List] is a Handler Collection that calls each handler in turn until either an exception is thrown, the response is committed or the request.isHandled() returns true. It can be used to combine handlers that conditionally handle a request.
* A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerWrapper.html Handler Wrapper] is a handler base class that can be use to daisy chain handlers together in the style of aspect-oriented programming.  For example, a standard web application is implemented by a chain of a context, session, security and servlet handlers.
+
* A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/HandlerWrapper.html Handler Wrapper] is a handler base class that can be used to daisy chain handlers together in the style of aspect-oriented programming.  For example, a standard web application is implemented by a chain of a context, session, security and servlet handlers.
 
* A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ContextHandlerCollection.html Context Handler Collection] uses the longest prefix of the request URI (the contextPath) to select a specific [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ContextHandler.html ContextHandler] to handle the request.  
 
* A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ContextHandlerCollection.html Context Handler Collection] uses the longest prefix of the request URI (the contextPath) to select a specific [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ContextHandler.html ContextHandler] to handle the request.  
  
== File Server ==
+
See also [[Jetty/Howto/Write_Jetty_Handler|How to Write a Jetty Handler]].
 +
 
 +
==Configuring a File Server ==
  
 
The following code from [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/FileServer.html FileServer.java] uses a HandlerList to combine the [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ResourceHandler.html ResourceHandler] with the [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/DefaultHandler.html DefaultHandler]:
 
The following code from [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/FileServer.html FileServer.java] uses a HandlerList to combine the [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ResourceHandler.html ResourceHandler] with the [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/DefaultHandler.html DefaultHandler]:
Line 155: Line 163:
 
</source>
 
</source>
  
The resource handler is passed the request first and looks for a matching file in the local directory to serve. If a file is not found, then the request is passed to the default handler which will generate a 404 (or favicon.ico).
+
The resource handler is passed the request first and looks for a matching file in the local directory to serve. If it does not find a file, the request passes to the default handler which generates a 404 (or favicon.ico).
  
=== File Server with XML ===
+
=== Configuring a File Server with XML ===
Now is a good time to remind you that the [[Jetty/Reference/jetty.xml syntax|Jetty XML]] configuration format is able to render simple Java code into XML configuration.  So the above FileServer example can be written with a little reordering in Jetty XML as follows:
+
Now is a good time to remind you that the [[Jetty/Reference/jetty.xml syntax|Jetty XML]] configuration format can render simple Java code into XML configuration.  So the File Server example above can be written with a little reordering in Jetty XML as follows:
 
<source lang="xml">
 
<source lang="xml">
 
<?xml version="1.0"?>
 
<?xml version="1.0"?>
Line 198: Line 206:
 
</source>
 
</source>
  
This XML file can be run from the [http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/FileServerXml.java FileServerXml.java] class:
+
You can run this XML file from the [http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/FileServerXml.java FileServerXml.java] class:
 
<source lang="java">
 
<source lang="java">
 
public class FileServerXml
 
public class FileServerXml
Line 213: Line 221:
 
</source>
 
</source>
  
=== File Server with spring ===
+
=== Using Spring to Configure a File Server ===
The Spring framework can also be used to assemble jetty servers.  The file server example above can be written in spring configuration as:
+
You can also use the Spring framework to assemble Jetty servers.  The file server example above can be written in Spring configuration as:
 
   
 
   
 
<source lang="xml">
 
<source lang="xml">
Line 250: Line 258:
 
</source>
 
</source>
  
See also the [[Jetty/Howto/Spring|Jetty Spring HOWTO]].
+
See also [[Jetty/Howto/Spring|How to Configure Jetty with Spring]].
  
== Contexts ==
+
== Setting Contexts ==
A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ContextHandler.html ContextHandler] is a HandlerWrapper that will respond only to requests that have a URI prefix that match the configured context path.  
+
A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ContextHandler.html ContextHandler] is a HandlerWrapper that responds only to requests that have a URI prefix that matches the configured context path.  
  
Requests that match the context path will have their path methods updated accordingly and the following optional context features applied as appropriate:
+
Requests that match the context path have their path methods updated accordingly, and the following optional context features applied as appropriate:
 
  * A Thread Context classloader.
 
  * A Thread Context classloader.
 
  * A set of attributes
 
  * A set of attributes
  * A set init parameters
+
  * A set of init parameters
 
  * A resource base (aka document root)
 
  * A resource base (aka document root)
 
  * A set of virtual host names
 
  * A set of virtual host names
Line 286: Line 294:
 
</source>
 
</source>
  
== Servlets ==  
+
== Creating Servlets ==  
  
 
Servlets are the standard way to provide application logic that handles HTTP requests. Servlets are like constrained Handlers with standard ways to map specific URIs to specific servlets. The following code is based on [http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/HelloServlet.java HelloServlet.java]:
 
Servlets are the standard way to provide application logic that handles HTTP requests. Servlets are like constrained Handlers with standard ways to map specific URIs to specific servlets. The following code is based on [http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/HelloServlet.java HelloServlet.java]:
 
<source lang="java">public class HelloServlet extends HttpServlet
 
<source lang="java">public class HelloServlet extends HttpServlet
 
{
 
{
 +
    private String greeting="Hello World";
 +
    public HelloServlet(){}
 +
    public HelloServlet(String greeting)
 +
    {
 +
        this.greeting=greeting;
 +
    }
 
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 
     {
 
     {
 
         response.setContentType("text/html");
 
         response.setContentType("text/html");
 
         response.setStatus(HttpServletResponse.SC_OK);
 
         response.setStatus(HttpServletResponse.SC_OK);
         response.getWriter().println("<h1>Hello World</h1>");
+
         response.getWriter().println("<h1>"+greeting+"</h1>");
 
         response.getWriter().println("session=" + request.getSession(true).getId());
 
         response.getWriter().println("session=" + request.getSession(true).getId());
 
     }
 
     }
Line 301: Line 315:
 
</source>
 
</source>
  
== ServletContext ==
+
== Setting a ServletContext ==
A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/servlet/ServletContextHandler.html ServletContextHandler] is a specialization of ContextHandler with support for standard servlets.  The following code from [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/OneServletContext.html OneServletContext] shows 3 instances of the helloworld servlet registered with a ServletContextHandler:
+
A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/servlet/ServletContextHandler.html ServletContextHandler] is a specialization of ContextHandler with support for standard servlets.  The following code from [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/embedded/OneServletContext.html OneServletContext] shows three instances of the helloworld servlet registered with a ServletContextHandler:
 
<source lang="java">
 
<source lang="java">
 
public class OneServletContext
 
public class OneServletContext
Line 324: Line 338:
 
</source>
 
</source>
  
== Web Application Context ==
+
== Setting a Web Application Context ==
  
 
A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/webapp/WebAppContext.html Web Applications context] is a variation of ServletContextHandler that uses the standard layout and web.xml to configure the servlets, filters and other features:
 
A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/webapp/WebAppContext.html Web Applications context] is a variation of ServletContextHandler that uses the standard layout and web.xml to configure the servlets, filters and other features:
Line 347: Line 361:
 
</source>
 
</source>
  
If during development, your application has not been assembled into a war file, then it can be run from its source components with something like:
+
If during development, you have not assembled your application into a WAR file, you can run it from its source components with something like:
  
 
<source lang="java">
 
<source lang="java">
Line 371: Line 385:
 
</source>
 
</source>
  
== Context Handler Collection ==  
+
== Configuring a Context Handler Collection ==  
 
A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ContextHandlerCollection.html Context Handler Collection] uses the longest prefix of the request URI (the contextPath) to select a specific context.  The following example combines the previous two examples in a single Jetty server:
 
A [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/server/handler/ContextHandlerCollection.html Context Handler Collection] uses the longest prefix of the request URI (the contextPath) to select a specific context.  The following example combines the previous two examples in a single Jetty server:
 
<source lang="java">
 
<source lang="java">
Line 382: Line 396:
 
         ServletContextHandler context0 = new ServletContextHandler(ServletContextHandler.SESSIONS);
 
         ServletContextHandler context0 = new ServletContextHandler(ServletContextHandler.SESSIONS);
 
         context0.setContextPath("/ctx0");
 
         context0.setContextPath("/ctx0");
        server0.setHandler(context);
 
 
         context0.addServlet(new ServletHolder(new HelloServlet()),"/*");
 
         context0.addServlet(new ServletHolder(new HelloServlet()),"/*");
 
         context0.addServlet(new ServletHolder(new HelloServlet("Buongiorno Mondo")),"/it/*");
 
         context0.addServlet(new ServletHolder(new HelloServlet("Buongiorno Mondo")),"/it/*");
Line 401: Line 414:
 
}
 
}
 
</source>
 
</source>
 +
 +
== Embedding JSP ==
 +
 +
Embedding JSP support can be a bit confusing if you look at the Jars under the lib/jsp directory in the jetty distribution.  This is because we have to ship from Eclipse with the JSP bundles that are marked up as OSGi bundles, which you cannot directly download from Maven Central.  There are dependencies available in Maven Central that work because they were the actual source for the OSGi bundles themselves.  The OSGi bundles are simply these Maven Central artifacts decomposed into a few extra bundles.
 +
 +
An example of what you can use follows:
 +
 +
<pre>
 +
[INFO] org.eclipse.jetty:jetty-jsp-2.1:jar:7.2.2-SNAPSHOT
 +
[INFO] +- org.eclipse.jetty:jetty-util:jar:7.2.2-SNAPSHOT:provided
 +
[INFO] +- org.mortbay.jetty:jsp-2.1-glassfish:jar:2.1.v20100127:provided
 +
[INFO] |  +- org.eclipse.jdt.core.compiler:ecj:jar:3.5.1:provided
 +
[INFO] |  +- org.mortbay.jetty:jsp-api-2.1-glassfish:jar:2.1.v20100127:provided
 +
[INFO] |  \- ant:ant:jar:1.6.5:provided
 +
[INFO] \- javax.servlet:servlet-api:jar:2.5:provided
 +
</pre>
 +
 +
You should be able to depend on one of the embedding aggregates that we provide to get these dependencies without too much trouble. 
 +
 +
http://repo2.maven.org/maven2/org/eclipse/jetty/aggregate
  
 
}}
 
}}

Latest revision as of 13:52, 23 April 2013



Introduction

Warning2.png
Jetty 7 and Jetty 8 are now EOL (End of Life)




THIS IS NOT THE DOCUMENTATION YOU ARE LOOKING FOR!!!!!






All development and stable releases are being performed with Jetty 9 and Jetty 10.






This wiki is now officially out of date and all content has been moved to the Jetty Documentation Hub






Direct Link to updated documentation: http://www.eclipse.org/jetty/documentation/current/embedding-jetty.html


Jetty has a slogan, "Don't deploy your application in Jetty, deploy Jetty in your application." What this means is that as an alternative to bundling your application as a standard WAR to be deployed in Jetty, Jetty is designed to be a software component that can be instantiated and used in a Java program just like any POJO. Put another way, running Jetty in embedded mode means putting an HTTP module into your application, rather than putting your application into an HTTP server.

This tutorial takes you step-by-step from the simplest Jetty server instantiation to running multiple web applications with standards-based deployment descriptors. The source for most of these examples is part of the standard Jetty project.

Before doing this tutorial, it is worth while to do the Hello World tutorial. This tutorial is also available as a Embedding Jetty Webinar recording.

Note.png
Jetty Version
The code in this tutorial is from Jetty 7, but should also work on Jetty 8. For the latest stable code, follow the links to the code xref from the latest release, which might vary slightly from the code examples given on this page.

Details

To embed a Jetty server, the following steps are typical:

  1. Create the server
  2. Add/Configure Connectors
  3. Add/Configure Handlers
  4. Add/Configure Servlets/Webapps to Handlers
  5. Start the server
  6. Wait (join the server to prevent main exiting)

Creating a Server

The following code from SimplestServer.java instantiates and runs the simplest possible Jetty server:

public class SimplestServer
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);
        server.start();
        server.join();
    }
}

This runs an HTTP server on port 8080. It is not a very useful server as it has no handlers and thus returns a 404 error for every request.


Writing Handlers

To produce a response to a request, Jetty requires a Handler to be set on the server. A handler may:

  • Examine/modify the HTTP request.
  • Generate the complete HTTP response.
  • Call another Handler (see HandlerWrapper).
  • Select one or many Handlers to call (see HandlerCollection).

Hello World Handler

The following code based on HelloHandler.java shows a simple hello world handler:

public class HelloHandler extends AbstractHandler
{
    public void handle(String target,Request baseRequest,HttpServletRequest request,HttpServletResponse response) 
        throws IOException, ServletException
    {
        response.setContentType("text/html;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        baseRequest.setHandled(true);
        response.getWriter().println("<h1>Hello World</h1>");
    }
}

The parameters passed to the handle method are:

  • target–the target of the request, which is either a URI or a name from a named dispatcher.
  • baseRequest–the Jetty mutable request object, which is always unwrapped.
  • request–the immutable request object, which might have been wrapped.
  • response–the response, which might have been wrapped.

The handler sets the response status, content-type and marks the request as handled before it generates the body of the response using a writer.

The following code from OneHandler.java shows how a Jetty server can use this handler:

public static void main(String[] args) throws Exception
{
    Server server = new Server(8080);
    server.setHandler(new HelloHandler());
 
    server.start();
    server.join();
}

You now know everything you need to know to write an HTTP server based on Jetty. However, complex request handling is typically built from multiple Handlers. We will look in later sections at how you can combine handlers like aspects. You can see some of the handlers available in Jetty in the org.eclipse.jetty.server.handler package.

Configuring Connectors

To configure the HTTP connectors that the server uses, you can set one or more connectors on the server. You can configure each connector with details such as interface, port, buffer sizes, timeouts, etc.

The following code is based on ManyConnectors.java and shows how to set and configure connectors for the Hello World example:

public class ManyConnectors
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server();
 
        SelectChannelConnector connector0 = new SelectChannelConnector();
        connector0.setPort(8080);
        connector0.setMaxIdleTime(30000);
        connector0.setRequestHeaderSize(8192);
 
        SelectChannelConnector connector1 = new SelectChannelConnector();
        connector1.setHost("127.0.0.1");
        connector1.setPort(8888);
        connector1.setThreadPool(new QueuedThreadPool(20));
        connector1.setName("admin");
 
        SslSelectChannelConnector ssl_connector = new SslSelectChannelConnector();
        String jetty_home = 
          System.getProperty("jetty.home","../jetty-distribution/target/distribution");
        System.setProperty("jetty.home",jetty_home);
        ssl_connector.setPort(8443);
        SslContextFactory cf = ssl_connector.getSslContextFactory();
        cf.setKeyStore(jetty_home + "/etc/keystore");
        cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
        cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
 
        server.setConnectors(new Connector[]{ connector0, connector1, ssl_connector });
 
        server.setHandler(new HelloHandler());
 
        server.start();
        server.join();
    }
}

Understanding Handler Collections, Wrappers and Scopes

Complex request handling is typically built from multiple Handlers that can be combined in various ways:

  • A Handler Collection holds a collection of other handlers and calls each handler in order. This is useful for combining statistics and logging handlers with the handler that generates the response.
  • A Handler List is a Handler Collection that calls each handler in turn until either an exception is thrown, the response is committed or the request.isHandled() returns true. It can be used to combine handlers that conditionally handle a request.
  • A Handler Wrapper is a handler base class that can be used to daisy chain handlers together in the style of aspect-oriented programming. For example, a standard web application is implemented by a chain of a context, session, security and servlet handlers.
  • A Context Handler Collection uses the longest prefix of the request URI (the contextPath) to select a specific ContextHandler to handle the request.

See also How to Write a Jetty Handler.

Configuring a File Server

The following code from FileServer.java uses a HandlerList to combine the ResourceHandler with the DefaultHandler:

public class FileServer
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server();
        SelectChannelConnector connector = new SelectChannelConnector();
        connector.setPort(8080);
        server.addConnector(connector);
 
        ResourceHandler resource_handler = new ResourceHandler();
        resource_handler.setDirectoriesListed(true);
        resource_handler.setWelcomeFiles(new String[]{ "index.html" });
 
        resource_handler.setResourceBase(".");
 
        HandlerList handlers = new HandlerList();
        handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
        server.setHandler(handlers);
 
        server.start();
        server.join();
    }
}

The resource handler is passed the request first and looks for a matching file in the local directory to serve. If it does not find a file, the request passes to the default handler which generates a 404 (or favicon.ico).

Configuring a File Server with XML

Now is a good time to remind you that the Jetty XML configuration format can render simple Java code into XML configuration. So the File Server example above can be written with a little reordering in Jetty XML as follows:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
 
<Configure id="FileServer" class="org.eclipse.jetty.server.Server">
 
    <Call name="addConnector">
      <Arg>
          <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
            <Set name="port">8080</Set>
          </New>
      </Arg>
    </Call>
 
    <Set name="handler">
      <New class="org.eclipse.jetty.server.handler.HandlerList">
        <Set name="handlers">
	  <Array type="org.eclipse.jetty.server.Handler">
	    <Item>
	      <New class="org.eclipse.jetty.server.handler.ResourceHandler">
	        <Set name="directoriesListed">true</Set>
		<Set name="welcomeFiles">
		  <Array type="String"><Item>index.html</Item></Array>
		</Set>
	        <Set name="resourceBase">.</Set>
	      </New>
	    </Item>
	    <Item>
	      <New class="org.eclipse.jetty.server.handler.DefaultHandler">
	      </New>
	    </Item>
	  </Array>
        </Set>
      </New>
    </Set>
</Configure>

You can run this XML file from the FileServerXml.java class:

public class FileServerXml
{
    public static void main(String[] args) throws Exception
    {
        Resource fileserver_xml = Resource.newSystemResource("fileserver.xml");
        XmlConfiguration configuration = new XmlConfiguration(fileserver_xml.getInputStream());
        Server server = (Server)configuration.configure();
        server.start();
        server.join();
    }
}

Using Spring to Configure a File Server

You can also use the Spring framework to assemble Jetty servers. The file server example above can be written in Spring configuration as:

<beans>
  <bean id="Server" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">
 
    <property name="connectors">
      <list>
        <bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector">
          <property name="port" value="8080"/>
        </bean>
      </list>
    </property>
 
    <property name="handler">
      <bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerList">
        <property name="handlers">
          <list>
            <bean class="org.eclipse.jetty.server.handler.ResourceHandler">
              <property name="directoriesListed" value="true"/>
              <property name="welcomeFiles">
                <list>
                  <value>index.html</value>
                </list>
              </property>
              <property name="resourceBase" value="."/>
            </bean>       
            <bean class="org.eclipse.jetty.server.handler.DefaultHandler"/>
          </list>
        </property>
      </bean>
    </property>
  </bean>
</beans>

See also How to Configure Jetty with Spring.

Setting Contexts

A ContextHandler is a HandlerWrapper that responds only to requests that have a URI prefix that matches the configured context path.

Requests that match the context path have their path methods updated accordingly, and the following optional context features applied as appropriate:

* A Thread Context classloader.
* A set of attributes
* A set of init parameters
* A resource base (aka document root)
* A set of virtual host names

Requests that don't match are not handled.

The following code is based on OneContext.java and sets context path and classloader for the hello handler:

public class OneContext
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);
 
        ContextHandler context = new ContextHandler();
        context.setContextPath("/hello");
        context.setResourceBase(".");
        context.setClassLoader(Thread.currentThread().getContextClassLoader());
        server.setHandler(context);
 
        context.setHandler(new HelloHandler());
 
        server.start();
        server.join();
    }
}

Creating Servlets

Servlets are the standard way to provide application logic that handles HTTP requests. Servlets are like constrained Handlers with standard ways to map specific URIs to specific servlets. The following code is based on HelloServlet.java:

public class HelloServlet extends HttpServlet
{
    private String greeting="Hello World";
    public HelloServlet(){}
    public HelloServlet(String greeting)
    {
        this.greeting=greeting;
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        response.setContentType("text/html");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().println("<h1>"+greeting+"</h1>");
        response.getWriter().println("session=" + request.getSession(true).getId());
    }
}

Setting a ServletContext

A ServletContextHandler is a specialization of ContextHandler with support for standard servlets. The following code from OneServletContext shows three instances of the helloworld servlet registered with a ServletContextHandler:

public class OneServletContext
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);
 
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);
 
        context.addServlet(new ServletHolder(new HelloServlet()),"/*");
        context.addServlet(new ServletHolder(new HelloServlet("Buongiorno Mondo")),"/it/*");
        context.addServlet(new ServletHolder(new HelloServlet("Bonjour le Monde")),"/fr/*");
 
        server.start();
        server.join();
    }
}

Setting a Web Application Context

A Web Applications context is a variation of ServletContextHandler that uses the standard layout and web.xml to configure the servlets, filters and other features:

public class OneWebApp
{
    public static void main(String[] args) throws Exception
    {
        String jetty_home = System.getProperty("jetty.home","..");
 
        Server server = new Server(8080);
 
        WebAppContext webapp = new WebAppContext();
        webapp.setContextPath("/");
        webapp.setWar(jetty_home+"/webapps/test.war");
        server.setHandler(webapp);
 
        server.start();
        server.join();
    }
}

If during development, you have not assembled your application into a WAR file, you can run it from its source components with something like:

public class OneWebAppUnassembled
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);
 
        WebAppContext context = new WebAppContext();
        context.setDescriptor(webapp+"/WEB-INF/web.xml");
        context.setResourceBase("../test-jetty-webapp/src/main/webapp");
        context.setContextPath("/");
        context.setParentLoaderPriority(true);
 
        server.setHandler(context);
 
        server.start();
        server.join();
    }
}

Configuring a Context Handler Collection

A Context Handler Collection uses the longest prefix of the request URI (the contextPath) to select a specific context. The following example combines the previous two examples in a single Jetty server:

public class ManyContexts
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);
 
        ServletContextHandler context0 = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context0.setContextPath("/ctx0");
        context0.addServlet(new ServletHolder(new HelloServlet()),"/*");
        context0.addServlet(new ServletHolder(new HelloServlet("Buongiorno Mondo")),"/it/*");
        context0.addServlet(new ServletHolder(new HelloServlet("Bonjour le Monde")),"/fr/*");
 
        WebAppContext webapp = new WebAppContext();
        webapp.setContextPath("/ctx1");
        webapp.setWar(jetty_home+"/webapps/test.war");
 
        ContextHandlerCollection contexts = new ContextHandlerCollection();
        contexts.setHandlers(new Handler[] { context0, webapp });
 
        server.setHandler(contexts);
 
        server.start();
        server.join();
    }
}

Embedding JSP

Embedding JSP support can be a bit confusing if you look at the Jars under the lib/jsp directory in the jetty distribution. This is because we have to ship from Eclipse with the JSP bundles that are marked up as OSGi bundles, which you cannot directly download from Maven Central. There are dependencies available in Maven Central that work because they were the actual source for the OSGi bundles themselves. The OSGi bundles are simply these Maven Central artifacts decomposed into a few extra bundles.

An example of what you can use follows:

[INFO] org.eclipse.jetty:jetty-jsp-2.1:jar:7.2.2-SNAPSHOT
[INFO] +- org.eclipse.jetty:jetty-util:jar:7.2.2-SNAPSHOT:provided
[INFO] +- org.mortbay.jetty:jsp-2.1-glassfish:jar:2.1.v20100127:provided
[INFO] |  +- org.eclipse.jdt.core.compiler:ecj:jar:3.5.1:provided
[INFO] |  +- org.mortbay.jetty:jsp-api-2.1-glassfish:jar:2.1.v20100127:provided
[INFO] |  \- ant:ant:jar:1.6.5:provided
[INFO] \- javax.servlet:servlet-api:jar:2.5:provided

You should be able to depend on one of the embedding aggregates that we provide to get these dependencies without too much trouble.

http://repo2.maven.org/maven2/org/eclipse/jetty/aggregate

Back to the top