Fixed documentation that was still referring to `Handler.process()` which has now become `Handler.handle()`.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2023-08-10 16:47:37 +02:00
parent 1a9f428b3d
commit eb35e42cb6
No known key found for this signature in database
GPG Key ID: 1677D141BCF3584D
8 changed files with 61 additions and 32 deletions

View File

@ -1,5 +1,8 @@
// Asciidoctor IDE configuration file.
// See https://github.com/asciidoctor/asciidoctor-intellij-plugin/wiki/Support-project-specific-configurations
:ee-all: ee{8,9,10}
:ee-current: ee10
:ee-current-caps: EE 10
:experimental:
:imagesdir: images
:doc_code: ../../java

View File

@ -46,6 +46,12 @@
| `org.eclipse.jetty.http2.client.**http**.*` | `org.eclipse.jetty.http2.client.**transport**.*`
|===
[[pg-migration-11-to-12-servlet-to-handler]]
==== Migrate Servlets to Jetty Handlers
[[pg-migration-11-to-12-api-changes]]
==== APIs Changes

View File

@ -21,12 +21,24 @@ The `Handler` API consist fundamentally of just one method:
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=handlerAPI]
----
The `target` parameter is an identifier for the resource.
This is normally the URI that is parsed from an HTTP request.
However, a request could be forwarded to either a named resource, in which case `target` will be the name of the resource, or to a different URI, in which case `target` will be the new URI.
The code that implements the `handle(\...)` method must respect the following contract:
Applications may wrap the request or response (or both) and forward the wrapped request or response to a different URI (which may be possibly handled by a different `Handler`).
This is the reason why there are two request parameters in the `Handler` APIs: the first is the unwrapped, original, request that also gives access to Jetty-specific APIs, while the second is the application-wrapped Servlet request.
* It may inspect `Request` immutable information such as URI and headers, typically to decide whether to return `true` or `false` (see below).
* Returning `false` means that the implementation does not handle the request, and it **must not** complete the `callback` parameter, nor read the request content, nor write response content.
* Returning `true` means that the implementation wants to handle the request, and it **must** eventually complete the `callback` parameter.
The completion of the `callback` parameter may happen synchronously within the invocation to `handle(\...)`, or at a later time, asynchronously, possibly from another thread.
If the response has not been explicitly written when `handle(\...)` returns, the implementation will write a `200` response with no content.
[CAUTION]
====
Violating the contract above may result in undefined or unexpected behavior.
For example, returning `true` from `handle(\...)`, but not completing the `callback` parameter may result in the request or the response never be completed, likely causing the client to time out.
Similarly, returning `false` from `handle(\...)` but then either writing the response or completing the `callback` parameter will likely result in a garbled response be sent to the client, as the implementation will either invoke another `Handler` (that may write a response) or write a default response.
====
Applications may wrap the request or response (or both) and forward the wrapped request or response to a child `Handler`.
[[pg-server-http-handler-impl-hello]]
====== Hello World Handler
@ -38,7 +50,10 @@ A simple "Hello World" `Handler` is the following:
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=handlerHello]
----
Such a simple `Handler` extends from `AbstractHandler` and can access the request and response main features, such as reading request headers and content, or writing response headers and content.
Such a simple `Handler` extends from `Handler.Abstract` and can access the request and response main features, such as reading request headers and content, or writing response headers and content.
Note how the `callback` parameter is passed to `Content.Sink.write(\...)` (a utility method that eventually calls `Response.write(\...)`), so that when the write completes, also the `callback` parameter is completed.
Note also that because the `callback` parameter will eventually be completed, the value returned from `handle(\...)` is `true`.
[[pg-server-http-handler-impl-filter]]
====== Filtering Handler

View File

@ -40,7 +40,7 @@ Web applications can be written using exclusively the Servlet APIs, since develo
Embedded web applications based on the Servlet APIs are described in xref:pg-server-http-handler-use-servlet[this section].
Embedded web applications may also require additional features such as access to Jetty specific APIs, or utility features such as redirection from HTTP to HTTPS, support for `gzip` content compression, etc.
The Jetty Server Libraries provides a number of out-of-the-box __Handler__s that implement the most common functionalities and are described in xref:pg-server-http-handler-use[this section].
The Jetty Server Libraries provides a number of out-of-the-box ``Handler``s that implement the most common functionalities and are described in the next sections.
[[pg-server-http-handler-use-util-context]]
====== ContextHandler
@ -75,9 +75,9 @@ However, this has no knowledge of the concept of _context_ and just iterates thr
A better choice for multiple web application is `ContextHandlerCollection`, that matches a _context_ from either its _context path_ or _virtual host_, without iterating through the ``Handler``s.
If `ContextHandlerCollection` does not find a match, it just returns `false` from its `process(\...)` method.
If `ContextHandlerCollection` does not find a match, it just returns `false` from its `handle(\...)` method.
What happens next depends on the `Handler` tree structure: other ``Handler``s may be invoked after `ContextHandlerCollection`, for example `DefaultHandler` (see xref:pg-server-http-handler-use-util-default-handler[this section]).
Eventually, if no `Handler` returns `true` from their own `process(\...)` method, then Jetty returns an HTTP `404` response to the client.
Eventually, if no `Handler` returns `true` from their own `handle(\...)` method, then Jetty returns an HTTP `404` response to the client.
[source,java,indent=0]
----
@ -132,7 +132,7 @@ If you need to serve static resources from multiple directories:
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=multipleResourcesHandler]
----
If the resource is not found, `ResourceHandler` will not return `true` from the `process(\...)` method, so what happens next depends on the `Handler` tree structure.
If the resource is not found, `ResourceHandler` will not return `true` from the `handle(\...)` method, so what happens next depends on the `Handler` tree structure.
See also xref:pg-server-http-handler-use-util-default-handler[how to use] `DefaultHandler`.
[[pg-server-http-handler-use-util-gzip-handler]]
@ -285,7 +285,7 @@ include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPSer
[[pg-server-http-handler-use-util-default-handler]]
====== DefaultHandler
`DefaultHandler` is a terminal `Handler` that always returns `true` from its `process(\...)` method and performs the following:
`DefaultHandler` is a terminal `Handler` that always returns `true` from its `handle(\...)` method and performs the following:
* Serves the `favicon.ico` Jetty icon when it is requested
* Sends a HTTP `404` response for any other request
@ -357,7 +357,7 @@ Note also how adding a `Servlet` or a `Filter` returns a _holder_ object that ca
When a request arrives to `ServletContextHandler` the request URI will be matched against the ``Filter``s and ``Servlet`` mappings and only those that match will process the request, as dictated by the Servlet specification.
IMPORTANT: `ServletContextHandler` is a terminal `Handler`, that is it always returns `true` from its `process(\...)` method when invoked.
IMPORTANT: `ServletContextHandler` is a terminal `Handler`, that is it always returns `true` from its `handle(\...)` method when invoked.
Server applications must be careful when creating the `Handler` tree to put ``ServletContextHandler``s as last ``Handler``s in any `Handler.Collection` or as children of a `ContextHandlerCollection`.
// TODO: revise what above, as ServletContextHandler is not a terminal handler.
@ -385,12 +385,11 @@ The web application class loader is special because it behaves differently from
The typical class loading model, parent-first, is _inverted_ for web application class loaders, as they use a child-first model.
Furthermore, the Servlet specification requires that web applications cannot load or otherwise access the Servlet container implementation classes, also called _server classes_.
In the Jetty case, the Servlet specification class `javax.servlet.http.HttpServletRequest` is implemented by `org.eclipse.jetty.server.Request`.
Web applications cannot downcast Servlet's `HttpServletRequest` to Jetty's `Request` to access Jetty specific features -- this ensures maximum web application portability across Servlet container implementations.
Web applications receive the HTTP request object as an instance of the `jakarta.servlet.http.HttpServletRequest` interface, and cannot downcast it to the Jetty specific implementation of that interface to access Jetty specific features -- this ensures maximum web application portability across Servlet container implementations.
Lastly, the Servlet specification requires that other classes, also called _system classes_, such as `javax.servlet.http.HttpServletRequest` or JDK classes such as `java.lang.String` or `java.sql.Connection` cannot be modified by web applications by putting, for example, modified versions of those classes in `WEB-INF/classes` so that they are loaded first by the web application class loader (instead of the class-path class loader where they are normally loaded from).
Lastly, the Servlet specification requires that other classes, also called _system classes_, such as `jakarta.servlet.http.HttpServletRequest` or JDK classes such as `java.lang.String` or `java.sql.Connection` cannot be modified by web applications by putting, for example, modified versions of those classes in `WEB-INF/classes` so that they are loaded first by the web application class loader (instead of the class-path class loader where they are normally loaded from).
`WebAppContext` implements this class loader logic using a single class loader, `org.eclipse.jetty.ee9.webapp.WebAppClassLoader`, with filtering capabilities: when it loads a class, it checks whether the class is a _system class_ or a _server class_ and acts according to the Servlet specification.
`WebAppContext` implements this class loader logic using a single class loader, `WebAppClassLoader`, with filtering capabilities: when it loads a class, it checks whether the class is a _system class_ or a _server class_ and acts according to the Servlet specification.
When `WebAppClassLoader` is asked to load a class, it first tries to find the class locally (since it must use the inverted child-first model); if the class is found, and it is not a _system class_, the class is loaded; otherwise the class is not found locally.
If the class is not found locally, the parent class loader is asked to load the class; the parent class loader uses the standard parent-first model, so it delegates the class loading to its parent, and so on.

View File

@ -17,12 +17,12 @@
An `org.eclipse.jetty.server.Handler` is the component that processes incoming HTTP requests and eventually produces HTTP responses.
``Handler``s can process the HTTP request themselves, or they can be ``Handler.Container``s that delegate HTTP request processing to one or more contained ``Handler``s.
This allows ``Handler``s to be organised as a tree comprised of:
This allows ``Handler``s to be organized as a tree comprised of:
* Leaf ``Handler``s that return `true` from the `process(\...)` method, generate a response and succeed the `Callback`.
* A `Handler.Wrapper` can be used to form a chain of ``Handler``s where request, response or callback objects are wrapped in the `process(\...)` method before being passed down the chain.
* A `Handler.Collection` that contains a sequence of ``Handler``s, with each `Handler` being called in sequence until one returns `true` from its `process(\..)` method.
* A specialized `Handler.Container` that may use properties of the request (for example, the URI, or a header, etc.) to select from one or more contained ``Handler``s to delegate the HTTP request processing to.
* Leaf ``Handler``s that return `true` from the `handle(\...)` method, generate a response and succeed the `Callback`.
* A `Handler.Wrapper` can be used to form a chain of ``Handler``s where request, response or callback objects are wrapped in the `handle(\...)` method before being passed down the chain.
* A `Handler.Sequence` that contains a sequence of ``Handler``s, with each `Handler` being called in sequence until one returns `true` from its `handle(\...)` method.
* A specialized `Handler.Container` that may use properties of the request (for example, the URI, or a header, etc.) to select from one or more contained ``Handler``s to delegate the HTTP request processing to, for example link:{javadoc-url}/org/eclipse/jetty/server/handler/PathMappingsHandler.html[`PathMappingsHandler`].
A `Handler` tree is created by composing ``Handler``s together:
@ -37,7 +37,7 @@ The corresponding `Handler` tree structure looks like the following:
----
Server
└── GzipHandler
└── Handler.Collection
└── Handler.Sequence
├── App1Handler
└── App2Handler
----

View File

@ -27,7 +27,7 @@ The Jetty server-side libraries provide:
* HTTP/2 low-level support, for applications that want to explicitly handle low-level HTTP/2 _sessions_, _streams_ and _frames_, via the xref:pg-server-http2[HTTP/2 libraries]
* HTTP/3 low-level support, for applications that want to explicitly handle low-level HTTP/3 _sessions_, _streams_ and _frames_, via the xref:pg-server-http3[HTTP/3 libraries]
* WebSocket support, for applications that want to embed a WebSocket server, via the xref:pg-server-websocket[WebSocket libraries]
* FCGI support, to delegate requests to python or similar scripting languages.
* FCGI support, to delegate requests to PHP, Python, Ruby or similar scripting languages.
include::compliance/server-compliance.adoc[]
include::http/server-http.adoc[]

View File

@ -479,10 +479,10 @@ public class HTTPServerDocs
@Override
// tag::handlerAPI[]
public boolean handle(Request request, Response response, Callback callback) throws Exception
{
return true;
}
// end::handlerAPI[]
{
return false;
}
}
}
@ -555,7 +555,7 @@ public class HTTPServerDocs
HttpURI newURI = HttpURI.build(uri).path(newPath).asImmutable();
// Modify the request object by wrapping the HttpURI
request = new Request.Wrapper(request)
Request newRequest = new Request.Wrapper(request)
{
@Override
public HttpURI getHttpURI()
@ -563,12 +563,17 @@ public class HTTPServerDocs
return newURI;
}
};
}
// Forward to the next Handler.
// Forward to the next Handler using the wrapped Request.
return super.handle(newRequest, response, callback);
}
else
{
// Forward to the next Handler as-is.
return super.handle(request, response, callback);
}
}
}
Server server = new Server();
Connector connector = new ServerConnector(server);

View File

@ -607,8 +607,9 @@ public interface Handler extends LifeCycle, Destroyable, Request.Handler
}
/**
* <p>A {@link Handler.Container} that contains a list of other {@code Handler}s that are
* tried in sequence by {@link #handle(Request, Response, Callback)}.</p>
* <p>A {@link Handler.Container} that contains a list of other {@link Handler}s
* whose {@link Handler#handle(Request, Response, Callback)} method is invoked
* in sequence until {@code true} is returned.</p>
*/
class Sequence extends AbstractContainer implements Collection
{