blob: c5d07f52ad92b295f4c6fa81ca978878bc380d48 [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter&nbsp;23.&nbsp;Handlers</title><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><meta name="keywords" content="jetty, servlet, servlet-api, cometd, http, websocket, eclipse, maven, java, server, software"><link rel="home" href="index.html" title="Jetty : The Definitive Reference"><link rel="up" href="development.html" title="Part&nbsp;IV.&nbsp;Jetty Development Guide"><link rel="prev" href="ant-and-jetty.html" title="Chapter&nbsp;22.&nbsp;Using Ant with Jetty"><link rel="next" href="advanced-embedding.html" title="Chapter&nbsp;24.&nbsp;Embedding"><link xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" rel="shortcut icon" href="images/favicon.ico"><script type="text/javascript" src="js/shCore.js"></script><script type="text/javascript" src="js/shBrushJava.js"></script><script type="text/javascript" src="js/shBrushXml.js"></script><script type="text/javascript" src="js/shBrushBash.js"></script><script type="text/javascript" src="js/shBrushJScript.js"></script><script type="text/javascript" src="js/shBrushSql.js"></script><script type="text/javascript" src="js/shBrushProperties.js"></script><script type="text/javascript" src="js/shBrushPlain.js"></script><link type="text/css" rel="stylesheet" href="css/shCore.css"><link type="text/css" rel="stylesheet" href="css/shThemeEclipse.css"><link type="text/css" rel="stylesheet" href="css/font-awesome.min.css"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><tr><td style="width: 25%"><a href="http://www.eclipse.org/jetty"><img src="images/jetty-header-logo.png" alt="Jetty Logo"></a><br><span style="font-size: small">
Version: 9.3.0.v20150612</span></td><td style="width: 50%"><script type="text/javascript"> (function() {
var cx = '016459005284625897022:obd4lsai2ds';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//www.google.com/cse/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script><gcse:search></gcse:search></td></tr></table><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter&nbsp;23.&nbsp;Handlers</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ant-and-jetty.html"><i class="icon-chevron-left"></i> Previous</a>&nbsp;</td><th width="60%" align="center">Part&nbsp;IV.&nbsp;Jetty Development Guide<br><a accesskey="p" href="index.html"><i class="icon-home"></i> Home</a></th><td width="20%" align="right">&nbsp;<a accesskey="n" href="advanced-embedding.html">Next <i class="icon-chevron-right"></i></a></td></tr></table><hr></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="jetty-callout"><h5 class="callout"><a href="http://www.webtide.com/">Contact the core Jetty developers at
<span class="website">www.webtide.com</span></a></h5><p>
private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ...
scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery
</p></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="jetty-handlers"></a>Chapter&nbsp;23.&nbsp;Handlers</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="jetty-handlers.html#writing-custom-handlers">Writing Custom Handlers</a></span></dt></dl></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="writing-custom-handlers"></a>Writing Custom Handlers</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="jetty-handlers.html#handler-api">The Handler API</a></span></dt><dt><span class="section"><a href="jetty-handlers.html#handling-requests">Handling Requests</a></span></dt><dt><span class="section"><a href="jetty-handlers.html#more-about-handlers">More About Handlers</a></span></dt></dl></div><p>The Handler is the Jetty component that deals with received
requests.</p><p>Many users of Jetty never need to write a Jetty Handler, but instead
use the <a class="link" href="http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/servlet/package-summary.html" target="_top">Servlet
API.</a> You can reuse the existing Jetty handlers for context, security,
sessions and servlets without the need for extension. However, some users
might have special requirements or footprint concerns that prohibit the use
of the full servlet API. For them implementing a Jetty handler is a straight
forward way to provide dynamic web content with a minimum of fuss.</p><p>See <a class="xref" href="architecture.html#basic-architecture" title="Jetty Architecture">Jetty Architecture</a> to understand more about
Handlers vs. Servlets.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="handler-api"></a>The Handler API</h3></div></div></div><p>The <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/Handler.html" target="_top">Handler</a>
interface provides Jetty's core of content generation or manipulation.
Classes that implement this interface are used to coordinate requests,
filter requests and generate content.</p><p>The core API of the Handler interface is: </p><div class="informalexample"><script type="syntaxhighlighter" class="brush: java;toolbar: false">
<![CDATA[public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException]]>
</script></div><p>An implementation of this method can handle a request, pass the
request onto another handler (or servlet), or it can modify and/or wrap
the request and then pass it on. This gives three styles of
handler:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Coordinating Handlers - Handlers that route requests to other
handlers (HandlerCollection, ContextHandlerCollection)</p></li><li class="listitem"><p>Filtering Handlers - Handlers that augment a request and pass it
on to other handlers (HandlerWrapper, ContextHandler,
SessionHandler)</p></li><li class="listitem"><p>Generating Handlers - Handlers that produce content
(ResourceHandler and ServletHandler)</p></li></ul></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="target"></a>The Target</h4></div></div></div><p>The target of a handler is an identifier for the resource that
should handle the passed request. This is normally the URI that is
parsed from an HTTP Request. However, in two key circumstances the
target may differ from the URI of the passed request:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>If the request has been dispatched to a named resource, such
as a named servlet, the target is the name of that resource.</p></li><li class="listitem"><p>If the request is being made by a call to <a class="link" href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/api/javax/servlet/RequestDispatcher.html" target="_top">Request
Dispatcher</a>, the target is the URI of the included resource
and is different to the URI of the actual request.</p></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="request-and-response"></a>The Request and Response</h4></div></div></div><p>The request and response objects used in the signature of the
handle method are <a class="link" href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/api/javax/servlet/http/HttpServletRequest.html" target="_top">
Servlet Request</a> and <a class="link" href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/api/javax/servlet/http/HttpServletResponse.html" target="_top">
Servlet Response</a>. These are the standard APIs and are moderately
restricted in what they can do to the request and response. More often
than not, access to the Jetty implementations of these classes is
required: <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/Request.html" target="_top">Request</a>
and <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/Response.html" target="_top">Response</a>.
However, as the request and response may be wrapped by handlers, filters
and servlets, it is not possible to pass the implementation directly.
The following mantra retrieves the core implementation objects from
under any wrappers:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: java;toolbar: false">
<![CDATA[Request base_request = request instanceof Request ? (Request)request : HttpConnection.getCurrentConnection().getRequest();
Response base_response = response instanceof Response ? (Response)response : HttpConnection.getCurrentConnection().getResponse();]]>
</script></div><p>Notice that if the handler passes the request on to another
handler, it should use the request/response objects passed in, and not
the base objects. This is to preserve any wrapping done by up stream
handlers.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="dispatch"></a>The Dispatch</h4></div></div></div><p>The dispatch argument indicates the state of the handling of the
call and may be:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>REQUEST == 1 - An original request received from a
connector.</p></li><li class="listitem"><p>FORWARD == 2 - A request being forwarded by a
RequestDispatcher.</p></li><li class="listitem"><p>INCLUDE == 4 - A request being included by a
RequestDispatcher.</p></li><li class="listitem"><p>ERROR == 8 - A request being forwarded to a error handler by
the container.</p></li></ul></div><p>These mostly have significance for servlet and related handlers.
For example, the security handler only applies authentication and
authorization to REQUEST dispatches.</p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="handling-requests"></a>Handling Requests</h3></div></div></div><p>A Handler may handle a request by:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><a class="xref" href="jetty-handlers.html#generating-response" title="Generating a Response">Generating a Response</a></p></li><li class="listitem"><p><a class="xref" href="jetty-handlers.html#filtering-request-or-response" title="Filtering the Request and/or Response">Filtering the Request and/or Response</a></p></li><li class="listitem"><p><a class="xref" href="jetty-handlers.html#passing-request-and-response" title="Passing the Request and Response to Another Handler">Passing the Request and Response to Another Handler</a></p></li></ul></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="generating-response"></a>Generating a Response</h4></div></div></div><p>The <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/embedded/OneHandler.html" target="_top">OneHandler</a>
embedded example shows how a simple handler can generate a
response.</p><p>You can use the normal servlet response API, which will typically
set some status, content headers and then write out the content:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: java;toolbar: false">
<![CDATA[ response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("<h1>Hello OneHandler</h1>");]]>
</script></div><p>It is also very important that a handler indicate that it has
completed handling the request and that the request should not be passed
to other handlers:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: java;toolbar: false">
<![CDATA[ Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
base_request.setHandled(true);
]]>
</script></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="filtering-request-or-response"></a>Filtering the Request and/or Response</h4></div></div></div><p>Once the base request or response object is obtained, you can
modify it. Typically you would make modifications to accomplish:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Breaking the URI into contextPath, servletPath and pathInfo
components.</p></li><li class="listitem"><p>Associating a resource base with a request for static
content.</p></li><li class="listitem"><p>Associating a session with a request.</p></li><li class="listitem"><p>Associating a security principal with a request.</p></li><li class="listitem"><p>Changing the URI and paths during a request dispatch forward
to another resource.</p></li></ul></div><p>You can also update the context of the request:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Setting the current threads context classloader.</p></li><li class="listitem"><p>Setting thread locals to identify the current
ServletContext.</p></li></ul></div><p>Typically Jetty passes a modified request to another handler and
undoes modifications in a finally block afterwards:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: java;toolbar: false">
<![CDATA[ try
{
base_request.setSession(a_session);
next_handler.handle(target,request,response,dispatch);
}
finally
{
base_request.setSession(old_session);
}]]>
</script></div><p>The classes that implement the <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/handler/HandlerWrapper.html" target="_top">HandlerWrapper</a>
class are typically handler filters of this style.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="passing-request-and-response"></a>Passing the Request and Response to Another Handler</h4></div></div></div><p>A handler might simply inspect the request and use the target,
request URI or other information to select another handler to pass the
request to. These handlers typically implement the <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/HandlerContainer.html" target="_top">HandlerContainer</a>
interface.</p><p>Examples include:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/handler/HandlerCollection.html" target="_top">Class
Handler Collection</a> - A collection of handlers, where each
handler is called regardless of the state of the request. This is
typically used to pass a request to a <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/handler/ContextHandlerCollection.html" target="_top">ContextHandlerCollection,</a>
and then the <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/handler/RequestLogHandler.html" target="_top">RequestLogHandler.</a></p></li><li class="listitem"><p><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/handler/HandlerList.html" target="_top">HandlerList</a>
- A list of handlers that are called in turn until the request state
is set as handled.</p></li><li class="listitem"><p><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/handler/ContextHandlerCollection.html" target="_top">ContextHandlerCollection</a>
- A collection of Handlers, of which one is selected by best match
for the context path.</p></li></ul></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="more-about-handlers"></a>More About Handlers</h3></div></div></div><p>See
<a class="link" href="http://download.eclipse.org/jetty/stable-9/xref/" target="_top">Jetty Latest Source XRef</a> and
<a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/" target="_top">Jetty Latest JavaDoc</a>
for detailed information on each Jetty handler.</p></div></div></div><script type="text/javascript">
SyntaxHighlighter.all()
</script><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ant-and-jetty.html"><i class="icon-chevron-left"></i> Previous</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="development.html"><i class="icon-chevron-up"></i> Top</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="advanced-embedding.html">Next <i class="icon-chevron-right"></i></a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;22.&nbsp;Using Ant with Jetty&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html"><i class="icon-home"></i> Home</a></td><td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;24.&nbsp;Embedding</td></tr></table></div><p xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><div class="jetty-callout">
See an error or something missing?
<span class="callout"><a href="http://github.com/jetty-project/jetty-documentation">Contribute to this documentation at
<span class="website"><i class="icon-github"></i> Github!</span></a></span><span style="float: right"><i>(Generated: 2015-06-15T13:18:29-05:00)</i></span></div></p><script xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1149868-7']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script></body></html>