Search code examples
javajettyjetty-12

Porting AbstractHandler implementation from Jetty 11 to Jetty 12


I have a class that extends AbstractHandler and overrides the handle method like this:

@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 
        throws IOException {

    // implementation details    

}

However, I see that AbstractHandler is deprecated in Jetty 12 and the method signature for handle has changed:

@Override
public boolean handle(Request request, Response response, Callback callback) throws Exception {
    
}

My questions are:

  • How can I access the baseRequest and request objects that I rely on in my Jetty 11 implementation?
  • What is the proper way to port my AbstractHandler subclass to work in Jetty 12?

Here is a summary of what my handler is doing:

  • Checks HttpServletRequest headers
  • Sets HttpServletResponse headers based on Request headers

Any help or examples of properly migrating an AbstractHandler implementation from Jetty 11 to Jetty 12 would be greatly appreciated!


Solution

  • What you appear to want is either Handler.Abstract or Handler.Wrapper.

    There is documentation on both at

    And there are examples in the jetty-examples project at

    Such as FormEndpoints (along with others in the /embedded/ tree)

    In short, you have an immutable Request and a mutable Response.

    The Request is a special purpose Content.Source for HTTP which handles the read/demand behaviors of the incoming request (be sure to check out the static methods on both of these types, as there are many handy convenience methods for common tasks)

    The Response is a special purpose Content.Sink for HTTP which handles the write behaviors of the outgoing request (also look at the static methods on these two types as well).

    The boolean Handler.handle(Request, Response, Callback) method has the following contract.

    • Returning true means that this Handler is going to handle the request. This means no further Handler implementations will be called by the Server dispatch. (this was the equivalent of baseRequest.setHandled(true) in Jetty 11 and older)
    • The Callback MUST eventually be completed by calling success() or failure() on it. (many of the methods can take the Callback and do the success/failure for you, eg: Response.write, Content.Sink.write, etc)
    • Returning true does not complete/finish the request/response, only the callback completes the request/response.

    If you want to mutate the request (to change something about it) for a different handler, then you must use a Handler.Wrapper and wrap the incoming request in a Request.Wrapper that modifies things to suite your needs and then call the nested handler.

    Tip: if you can avoid using the Stream APIs from Content.Sink and Content.Source you'll have far better performance (and less resource use) in your webapp. But we know that sometimes that is not possible, so don't hesitate to use them.