Wiki
Clone wikijettyBuilder / Home
#JettyBuilder - A Groovy Builder for Configuring Jetty JettyBuilder allows you to embed and completely configure Jetty in your application in a declarative and concise fashion. It accomplishes this by employing a common idiom in Groovy, builders. Builders handle the busywork of creating complex objects for you, such as instantiating children, calling Jetty methods, and attaching these children to their parents. As a consequence, your code is much more readable and maintainable, while still allowing you access to the full range of Jetty components.
Here is an example of a JettyBuilder script:
#!groovy server( port: 8095, stopAtShutdown: true, stopTimeout: 5000 )
In this script, we're telling the builder to create a Server
using the Server(port)
constructor and set its bean properties stopAtShutdown
and stopTimeout
to the supplied values.
JettyBuilder is aware of which settings are constructor only vs bean-like as well as the sequence of creating objects, i.e child first then parent (default) vs. parent first then child (e.g. in the case of ServerConnector[child] and Server[parent]).
Embedded
We can embed this script in an application like this:
#!groovy class SimplestServer { static void main( String[] args ) throws Exception { server = new JettyBuilder().build { server( port: 8095, stopAtShutdown: true, stopTimeout: 5000 ) } server.start() } }
This runs an HTTP server on port 8080. Since this server has no handlers, it returns a 404
error for every request.
Script File
We can also place the builder script in a separate file with a .getty
extension. JettyBuilder automatically injects a builder instance jetty
. Lets call the script server.getty
:
jetty.server( port: 8095, stopAtShutdown: true, stopTimeout: 5000 )
Our app changes a bit to reference the external script like this:
#!groovy class SimplestServer { static void main( String[] args ) throws Exception { Server server = JettyBuilder.fromScript( "server.getty" ) server.start() } }
###Variables & Binding
Under the hood, JettyBuilder loads the script via GroovyShell
. This means we can use custom variables in our script and bind them to runtime values like this:
#!groovy jetty.server( port: httpPort ?: 8095, stopAtShutdown: true, stopTimeout: stopTimeout: ?: 5000 )
Script variables can be set by providing an optional map to fromScript
:
#!groovy Server server = JettyBuilder.fromScript("server.getty", [httpPort: 8080] )
The server now runs on port 8080. Note that we didn't bind stopTimeout
but since we used the Groovy elvis operator ?:
in the script, the server's stopTimeout will be set to a default 5000.
###Object Ids
Builder objects support a special property id
. This lets us reference the object instance elsewhere in the script
#!groovy jetty.server( id: "theServer", port: port, stopAtShutdown: true, stopTimeout: 5000 ) println theServer
Within the script, the variable theServer
holds a reference to the server instance. One place this is useful is with HttpConfiguration
copy constructors.
###Adding A Connector & Handlers Lets add a connector to our server and a couple of handlers:
#!groovy jetty.server( id: "theServer", stopAtShutdown: true, stopTimeout: 5000 ) { connector( port: httpPort ?: 8095, host: host ?: "localhost", idleTimeout: 30000 ) handlerList { resourceHandler( resourceBase: "/", directoriesListed: true ) defaultHandler( showContexts: true ) } }
This creates an HTTP server and adds a ServerConnector
object with defaults (i.e. no explicit connection factories). We also added two handlers, a ResourceHandler
and a DefaultHandler
for 404 handling. Also by convention, a Server
can have only one direct Handler
child so we wrapped the two handlers within a HandlerList
.
###Implicit use of HandlerList
Since we're asking the underlying builder to deal with the jetty API details, as a design decision we allow multiple top level Handler
objects as direct children of a Server
. In this case, we implicitly wrap multiple top-level handlers in a HandlerList
. Which means this is equivalent to the above and just a bit more concise:
#!groovy jetty.server( id: "theServer", stopAtShutdown: true, stopTimeout: 5000 ) { connector( port: httpPort ?: 8095, host: host ?: "localhost", idleTimeout: 30000 ) resourceHandler( resourceBase: "/", directoriesListed: true ) defaultHandler( showContexts: true ) }
###ServletHandler
Here's an example of a ServletHandler
with two servlets each mapped to a path:
#!groovy jetty.server( id: "theServer", stopAtShutdown: true, stopTimeout: 5000 ) { connector( port: httpPort ?: 8095, host: host ?: "localhost", idleTimeout: 30000 ) servletHandler servlets: [ "/hello": "com.maestro.groovy.builders.jettyBuilder.HelloServlet", "/hello2": "com.maestro.groovy.builders.jettyBuilder.HelloServlet", ] defaultHandler() }
###ServletContextHandler The following example instantiates a DefaultServlet to server static content from /tmp/ and a DumpServlet that creates a session and dumps basic details about the request:
#!groovy jetty.server( id: "theServer", port: port, stopAtShutdown: true, stopTimeout: 5000 ) { servletContextHandler useSessions: true, contextPath: "/", servlets: [ "/tmp/*": servletHolder( DefaultServlet, initParameters: [ resourceBase: "/tmp", pathInfoOnly: "true" ] ), "/*": servletHolder( DumpServlet ) ] }
###WebApp The following example configures the Jetty test webapp. Web applications can use resources the container provides, and in this case a LoginService is needed and also configured:
#!groovy jetty.server( id: "theServer", port: port, stopAtShutdown: true, stopTimeout: 5000 ) { webAppContext contextPath: "/", war: "src/test/resources/webapp/test-jetty-webapp-9.0.0-SNAPSHOT.war" hashLoginService name: "Test Realm", config: "src/test/resources/realm.properties" }
Updated