http://www.eclipse.org/jetty/documentation/current/embedding-jetty.html#d0e18726
![]() Version: 9.2.2-SNAPSHOT |
|
Contact the core Jetty developers at www.webtide.com
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
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.
To embed a Jetty server the following steps are typical and are illustrated by the examples in this tutorial:
-
Create a Server instance.
-
Add/Configure Connectors.
-
Start the Server.
-
Wait on the server or do something else with your thread.
The following code from SimplestServer.java instantiates and runs the simplest possible Jetty server:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
org.eclipse.jetty.server.Server;
/* ------------------------------------------------------------ */
/** The simplest possible Jetty server.
*/
public
class
SimplestServer
{
public
static
void
main(String[] args)
throws
Exception
{
Server server =
new
Server(
8080
);
server.start();
server.dumpStdErr();
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.
To produce a response to a request, Jetty requires that you set a Handler 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).
The following code based on HelloHandler.java shows a simple hello world handler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
java.io.IOException;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.eclipse.jetty.server.Request;
import
org.eclipse.jetty.server.handler.AbstractHandler;
public
class
HelloHandler
extends
AbstractHandler
{
final
String _greeting;
final
String _body;
public
HelloHandler()
{
_greeting=
"Hello World"
;
_body=
null
;
}
public
HelloHandler(String greeting)
{
_greeting=greeting;
_body=
null
;
}
public
HelloHandler(String greeting,String body)
{
_greeting=greeting;
_body=body;
}
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>"
+_greeting+
"</h1>"
);
if
(_body!=
null
)
response.getWriter().println(_body);
}
}
|
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 may have been wrapped by a filter or servlet.
-
response–the response, which may have been wrapped by a filter or servlet.
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.
To allow a Handler to handle HTTP requests, you must add it to a Server instance. The following code from OneHandler.java shows how a Jetty server can use the HelloWorld handler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
org.eclipse.jetty.server.Server;
public
class
OneHandler
{
public
static
void
main(String[] args)
throws
Exception
{
Server server =
new
Server(
8080
);
server.setHandler(
new
HelloHandler());
server.start();
server.join();
}
}
|
One or more handlers do all request handling in Jetty. Some handlers select other specific handlers (for example, a ContextHandlerCollection uses the context path to select a ContextHandler); others use application logic to generate a response (for example, the ServletHandler passes the request to an application Servlet), while others do tasks unrelated to generating the response (for example, RequestLogHandler or StatisticsHandler).
Later sections describe how you can combine handlers like aspects. You can see some of the handlers available in Jetty in theorg.eclipse.jetty.server.handler package.
Complex request handling is typically built from multiple Handlers that you can combine in various ways. Jetty has several implementations of the HandlerContainer interface:
-
HandlerCollection
-
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.
HandlerList
-
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. You can use it to combine handlers that conditionally handle a request, such as calling multiple contexts until one matches a virtual host.
HandlerWrapper
-
A Handler base class that you can 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.
ContextHandlerCollection
-
A specialized HandlerCollection that uses the longest prefix of the request URI (the contextPath) to select a contained ContextHandler to handle the request.
Much of the standard Servlet container in Jetty is implemented with HandlerWrappers that daisy chain handlers together: ContextHandler to SessionHandler to SecurityHandler to ServletHandler. However, because of the nature of the servlet specification, this chaining cannot be a pure nesting of handlers as the outer handlers sometimes need information that the inner handlers process. For example, when a ContextHandler calls some application listeners to inform them of a request entering the context, it must already know which servlet the ServletHandler will dispatch the request to so that the servletPath method returns the correct value.
The HandlerWrapper is specialized to the ScopedHandler abstract class, which supports a daisy chain of scopes. For example if a ServletHandler is nested withing a ContextHandler, the order and nesting of execution of methods is:
Server.handle(...)
ContextHandler.doScope(...)
ServletHandler.doScope(...)
ContextHandler.doHandle(...)
ServletHandler.doHandle(...)
SomeServlet.service(...)
Thus when the ContextHandler handles the request, it does so within the scope the ServletHandler has established.
The FileServer example shows how you can use a ResourceHandler to serve static content from the current working directory:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
org.eclipse.jetty.server.Handler;
import
org.eclipse.jetty.server.Server;
import
org.eclipse.jetty.server.handler.DefaultHandler;
import
org.eclipse.jetty.server.handler.HandlerList;
import
org.eclipse.jetty.server.handler.ResourceHandler;
/* ------------------------------------------------------------ */
/** Simple Jetty FileServer.
* This is a simple example of Jetty configured as a FileServer.
*/
public
class
FileServer
{
public
static
void
main(String[] args)
throws
Exception
{
// Create a basic Jetty server object that will listen on port 8080. Note that if you set this to port 0
// then a randomly available port will be assigned that you can either look in the logs for the port,
// or programmatically obtain it for use in test cases.
Server server =
new
Server(
8080
);
// Create the ResourceHandler. It is the object that will actually handle the request for a given file. It is
// a Jetty Handler object so it is suitable for chaining with other handlers as you will see in other examples.
ResourceHandler resource_handler =
new
ResourceHandler();
// Configure the ResourceHandler. Setting the resource base indicates where the files should be served out of.
// In this example it is the current directory but it can be configured to anything that the jvm has access to.
resource_handler.setDirectoriesListed(
true
);
resource_handler.setWelcomeFiles(
new
String[]{
"index.html"
});
resource_handler.setResourceBase(
"."
);
// Add the ResourceHandler to the server.
HandlerList handlers =
new
HandlerList();
handlers.setHandlers(
new
Handler[] { resource_handler,
new
DefaultHandler() });
server.setHandler(handlers);
// Start things up! By using the server.join() the server thread will join with the current thread.
// See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details.
server.start();
server.join();
}
}
|
Notice that a HandlerList is used with the ResourceHandler and a DefaultHandler, so that the DefaultHandler generates a good 404 response for any requests that do not match a static resource.
In the previous examples, the Server instance is passed a port number and it internally creates a default instance of a Connector that listens for requests on that port. However, often when embedding Jetty it is desirable to explicity instantiate and configure one or more Connectors for a Server instance.
The following example, OneConnector.java, instantiates, configures, and adds a single HTTP connector instance to the server:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
org.eclipse.jetty.server.Server;
import
org.eclipse.jetty.server.ServerConnector;
/* ------------------------------------------------------------ */
/**
* A Jetty server with one connectors.
*/
public
class
OneConnector
{
public
static
void
main(String[] args)
throws
Exception
{
// The Server
Server server =
new
Server();
// HTTP connector
ServerConnector http =
new
ServerConnector(server);
http.setHost(
"localhost"
);
http.setPort(
8080
);
http.setIdleTimeout(
30000
);
// Set the connector
server.addConnector(http);
// Set a handler
server.setHandler(
new
HelloHandler());
// Start the server
server.start();
server.join();
}
}
|
In this example the connector handles the HTTP protocol, as that is the default for the ServerConnector class.
When configuring multiple connectors (for example, HTTP and HTTPS), it may be desirable to share configuration of common parameters for HTTP. To achieve this you need to explicitly configure the ServerConnector class with ConnectionFactory instances, and provide them with common HTTP configuration.
The ManyConnectors example, configures a server with two ServerConnector instances: the http connector has a HTTPConnectionFactoryinstance; the https connector has a SslConnectionFactory chained to a HttpConnectionFactory. Both HttpConnectionFactories are configured based on the same HttpConfiguration instance, however the HTTPS factory uses a wrapped configuration so that a SecureRequestCustomizercan be added.
The SPDYConnector example is a similar to the HTTPS connector except that the SslConnectionFactory is chained to the NPNConnectionFactory that negotiates whether the next protocol is to be SPDY/2, SPDY/3 or HTTPS.
Servlets are the standard way to provide application logic that handles HTTP requests. Servlets are similar to a Jetty Handler except that the request object is not mutable and thus cannot be modified. Servlets are handled in Jetty by A ServletHandler. It uses standard path mappings to match a Servlet to a request; sets the requests servletPath and pathInfo; passes the request to the servlet, possibly via Filters to produce a response.
The MinimalServlets example creates a ServletHandler instance and configures a single HelloServlet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
java.io.IOException;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.eclipse.jetty.server.Server;
import
org.eclipse.jetty.servlet.ServletHandler;
public
class
MinimalServlets
{
public
static
void
main(String[] args)
throws
Exception
{
// Create a basic jetty server object that will listen on port 8080. Note that if you set this to port 0
// then a randomly available port will be assigned that you can either look in the logs for the port,
// or programmatically obtain it for use in test cases.
Server server =
new
Server(
8080
);
// The ServletHandler is a dead simple way to create a context handler that is backed by an instance of a
// Servlet. This handler then needs to be registered with the Server object.
ServletHandler handler =
new
ServletHandler();
server.setHandler(handler);
// Passing in the class for the servlet allows jetty to instantite an instance of that servlet and mount it
// on a given context path.
// !! This is a raw Servlet, not a servlet that has been configured through a web.xml or anything like that !!
handler.addServletWithMapping(HelloServlet.
class
,
"/*"
);
// Start things up! By using the server.join() the server thread will join with the current thread.
// See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details.
server.start();
server.join();
}
@SuppressWarnings
(
"serial"
)
public
static
class
HelloServlet
extends
HttpServlet
{
@Override
protected
void
doGet(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException
{
response.setContentType(
"text/html"
);
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println(
"<h1>Hello SimpleServlet</h1>"
);
}
}
}
|
A ContextHandler is a ScopedHandler 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 contexts scope is available, which optionally may include:
-
A Classloader that is set as the Thread context classloader while request handling is in scope.
-
A set of attributes that is available via the ServletContext API.
-
A set of init parameters that is available via the ServletContext API.
-
A base Resource which is used as the document root for static resource requests via the ServletContext API.
-
A set of virtual host names.
The following OneContext example shows a context being established that wraps the HelloHandler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
org.eclipse.jetty.server.Server;
import
org.eclipse.jetty.server.handler.ContextHandler;
public
class
OneContext
{
public
static
void
main(String[] args)
throws
Exception
{
Server server =
new
Server(
8080
);
ContextHandler context =
new
ContextHandler();
context.setContextPath(
"/"
);
context.setResourceBase(
"."
);
context.setClassLoader(Thread.currentThread().getContextClassLoader());
context.setHandler(
new
HelloHandler());
server.setHandler(context);
server.start();
server.join();
}
}
|
When many contexts are present, you can embed a ContextHandlerCollection to efficiently examine a request URI to then select the matching ContextHandler(s) for the request. The ManyContexts example shows how many such contexts you can configure:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
org.eclipse.jetty.server.Handler;
import
org.eclipse.jetty.server.Server;
import
org.eclipse.jetty.server.handler.ContextHandler;
import
org.eclipse.jetty.server.handler.ContextHandlerCollection;
public
class
ManyContexts
{
public
static
void
main(String[] args)
throws
Exception
{
Server server =
new
Server(
8080
);
ContextHandler context =
new
ContextHandler(
"/"
);
context.setContextPath(
"/"
);
context.setHandler(
new
HelloHandler(
"Root Hello"
));
ContextHandler contextFR =
new
ContextHandler(
"/fr"
);
contextFR.setHandler(
new
HelloHandler(
"Bonjoir"
));
ContextHandler contextIT =
new
ContextHandler(
"/it"
);
contextIT.setHandler(
new
HelloHandler(
"Bongiorno"
));
ContextHandler contextV =
new
ContextHandler(
"/"
);
contextV.setVirtualHosts(
new
String[]{
"127.0.0.2"
});
contextV.setHandler(
new
HelloHandler(
"Virtual Hello"
));
ContextHandlerCollection contexts =
new
ContextHandlerCollection();
contexts.setHandlers(
new
Handler[] { context, contextFR, contextIT, contextV });
server.setHandler(contexts);
server.start();
server.join();
}
}
|
A ServletContextHandler is a specialization of ContextHandler with support for standard sessions and Servlets. The following OneServletContext example instantiates a DefaultServlet to server static content from /tmp/ and a DumpServlet that creates a session and dumps basic details about the request:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
org.eclipse.jetty.server.Server;
import
org.eclipse.jetty.servlet.ServletContextHandler;
import
org.eclipse.jetty.servlet.ServletHolder;
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(org.eclipse.jetty.servlet.DefaultServlet.
class
,
"/"
);
context.addServlet(
new
ServletHolder(
new
DumpServlet()),
"/dump/*"
);
server.start();
server.join();
}
}
|
A WebAppContext is an extension of a ServletContextHandler that uses the standard layout and web.xml to configure the servlets, filters and other features from a web.xml and/or annotations. The following OneWebApp 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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
java.lang.management.ManagementFactory;
import
org.eclipse.jetty.jmx.MBeanContainer;
import
org.eclipse.jetty.security.HashLoginService;
import
org.eclipse.jetty.server.Server;
import
org.eclipse.jetty.webapp.WebAppContext;
public
class
OneWebApp
{
public
static
void
main(String[] args)
throws
Exception
{
// Create a basic jetty server object that will listen on port 8080. Note that if you set this to port 0 then
// a randomly available port will be assigned that you can either look in the logs for the port,
// or programmatically obtain it for use in test cases.
Server server =
new
Server(
8080
);
// Setup JMX
MBeanContainer mbContainer=
new
MBeanContainer(ManagementFactory.getPlatformMBeanServer());
server.addBean(mbContainer);
// The WebAppContext is the entity that controls the environment in which a web application lives and
// breathes. In this example the context path is being set to "/" so it is suitable for serving root context
// requests and then we see it setting the location of the war. A whole host of other configurations are
// available, ranging from configuring to support annotation scanning in the webapp (through
// PlusConfiguration) to choosing where the webapp will unpack itself.
WebAppContext webapp =
new
WebAppContext();
webapp.setContextPath(
"/"
);
webapp.setWar(
"../../jetty-distribution/target/distribution/demo-base/webapps/test.war"
);
// A WebAppContext is a ContextHandler as well so it needs to be set to the server so it is aware of where to
// send the appropriate requests.
server.setHandler(webapp);
// Configure a LoginService
// Since this example is for our test webapp, we need to setup a LoginService so this shows how to create a
// very simple hashmap based one. The name of the LoginService needs to correspond to what is configured in
// the webapp's web.xml and since it has a lifecycle of its own we register it as a bean with the Jetty
// server object so it can be started and stopped according to the lifecycle of the server itself.
HashLoginService loginService =
new
HashLoginService();
loginService.setName(
"Test Realm"
);
loginService.setConfig(
"src/test/resources/realm.properties"
);
server.addBean(loginService);
// Start things up! By using the server.join() the server thread will join with the current thread.
// See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details.
server.start();
server.join();
}
}
|
The typical way to configure an instance of the Jetty server is via jetty.xml
and associated configuration files. However the Jetty XML configuration format is just a simple rendering of what you can do in code; it is very simple to write embedded code that does precisely what the jetty.xml configuration does. The LikeJettyXml example following renders in code the behaviour obtained from the configuration files:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
//
// The Apache License v2.0 is available at
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package
org.eclipse.jetty.embedded;
import
java.lang.management.ManagementFactory;
import
org.eclipse.jetty.deploy.DeploymentManager;
import
org.eclipse.jetty.deploy.PropertiesConfigurationManager;
import
org.eclipse.jetty.deploy.providers.WebAppProvider;
import
org.eclipse.jetty.jmx.MBeanContainer;
import
org.eclipse.jetty.security.HashLoginService;
import
org.eclipse.jetty.server.Handler;
import
org.eclipse.jetty.server.HttpConfiguration;
import
org.eclipse.jetty.server.HttpConnectionFactory;
import
org.eclipse.jetty.server.LowResourceMonitor;
import
org.eclipse.jetty.server.NCSARequestLog;
import
org.eclipse.jetty.server.SecureRequestCustomizer;
import
org.eclipse.jetty.server.Server;
import
org.eclipse.jetty.server.ServerConnector;
import
org.eclipse.jetty.server.SslConnectionFactory;
import
org.eclipse.jetty.server.handler.ContextHandlerCollection;
import
org.eclipse.jetty.server.handler.DefaultHandler;
import
org.eclipse.jetty.server.handler.HandlerCollection;
import
org.eclipse.jetty.server.handler.RequestLogHandler;
import
org.eclipse.jetty.server.handler.StatisticsHandler;
import
org.eclipse.jetty.util.ssl.SslContextFactory;
import
org.eclipse.jetty.util.thread.QueuedThreadPool;
import
org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
public
class
LikeJettyXml
{
public
static
void
main(String[] args)
throws
Exception
{
String jetty_home = System.getProperty(
"jetty.home"
,
"../../jetty-distribution/target/distribution"
);
String jetty_base = System.getProperty(
"jetty.home"
,
"../../jetty-distribution/target/distribution/demo-base"
);
System.setProperty(
"jetty.home"
,jetty_home);
System.setProperty(
"jetty.base"
,jetty_base);
// === jetty.xml ===
// Setup Threadpool
QueuedThreadPool threadPool =
new
QueuedThreadPool();
threadPool.setMaxThreads(
500
);
// Server
Server server =
new
Server(threadPool);
// Scheduler
server.addBean(
new
ScheduledExecutorScheduler());
// HTTP Configuration
HttpConfiguration http_config =
new
HttpConfiguration();
http_config.setSecureScheme(
"https"
);
http_config.setSecurePort(
8443
);
http_config.setOutputBufferSize(
32768
);
http_config.setRequestHeaderSize(
8192
);
http_config.setResponseHeaderSize(
8192
);
http_config.setSendServerVersion(
true
);
http_config.setSendDateHeader(
false
);
// httpConfig.addCustomizer(new ForwardedRequestCustomizer());
// Handler Structure
HandlerCollection handlers =
new
HandlerCollection();
ContextHandlerCollection contexts =
new
ContextHandlerCollection();
handlers.setHandlers(
new
Handler[] { contexts,
new
DefaultHandler() });
server.setHandler(handlers);
// Extra options
server.setDumpAfterStart(
false
);
server.setDumpBeforeStop(
false
);
server.setStopAtShutdown(
true
);
// === jetty-jmx.xml ===
MBeanContainer mbContainer=
new
MBeanContainer(ManagementFactory.getPlatformMBeanServer());
server.addBean(mbContainer);
// === jetty-http.xml ===
ServerConnector http =
new
ServerConnector(server,
new
HttpConnectionFactory(http_config));
http.setPort(
8080
);
http.setIdleTimeout(
30000
);
server.addConnector(http);
// === jetty-https.xml ===
// SSL Context Factory
SslContextFactory sslContextFactory =
new
SslContextFactory();
sslContextFactory.setKeyStorePath(jetty_home +
"/etc/keystore"
);
sslContextFactory.setKeyStorePassword(
"OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"
);
sslContextFactory.setKeyManagerPassword(
"OBF:1u2u1wml1z7s1z7a1wnl1u2g"
);
sslContextFactory.setTrustStorePath(jetty_home +
"/etc/keystore"
);
sslContextFactory.setTrustStorePassword(
"OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"
);
sslContextFactory.setExcludeCipherSuites(
"SSL_RSA_WITH_DES_CBC_SHA"
,
"SSL_DHE_RSA_WITH_DES_CBC_SHA"
,
"SSL_DHE_DSS_WITH_DES_CBC_SHA"
,
"SSL_RSA_EXPORT_WITH_RC4_40_MD5"
,
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"
,
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"
,
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
);
// SSL HTTP Configuration
HttpConfiguration https_config =
new
HttpConfiguration(http_config);
https_config.addCustomizer(
new
SecureRequestCustomizer());
// SSL Connector
ServerConnector sslConnector =
new
ServerConnector(server,
new
SslConnectionFactory(sslContextFactory,
"http/1.1"
),
new
HttpConnectionFactory(https_config));
sslConnector.setPort(
8443
);
server.addConnector(sslConnector);
// === jetty-deploy.xml ===
DeploymentManager deployer =
new
DeploymentManager();
deployer.setContexts(contexts);
deployer.setContextAttribute(
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern"
,
".*/servlet-api-[^/]*\\.jar$"
);
WebAppProvider webapp_provider =
new
WebAppProvider();
webapp_provider.setMonitoredDirName(jetty_base +
"/webapps"
);
webapp_provider.setDefaultsDescriptor(jetty_home +
"/etc/webdefault.xml"
);
webapp_provider.setScanInterval(
1
);
webapp_provider.setExtractWars(
true
);
webapp_provider.setConfigurationManager(
new
PropertiesConfigurationManager());
deployer.addAppProvider(webapp_provider);
server.addBean(deployer);
// === jetty-stats.xml ===
StatisticsHandler stats =
new
StatisticsHandler();
stats.setHandler(server.getHandler());
server.setHandler(stats);
// === jetty-requestlog.xml ===
NCSARequestLog requestLog =
new
NCSARequestLog();
requestLog.setFilename(jetty_home +
"/logs/yyyy_mm_dd.request.log"
);
requestLog.setFilenameDateFormat(
"yyyy_MM_dd"
);
requestLog.setRetainDays(
90
);
requestLog.setAppend(
true
);
requestLog.setExtended(
true
);
requestLog.setLogCookies(
false
);
requestLog.setLogTimeZone(
"GMT"
);
RequestLogHandler requestLogHandler =
new
RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
handlers.addHandler(requestLogHandler);
// === jetty-lowresources.xml ===
LowResourceMonitor lowResourcesMonitor=
new
LowResourceMonitor(server);
lowResourcesMonitor.setPeriod(
1000
);
lowResourcesMonitor.setLowResourcesIdleTimeout(
200
);
lowResourcesMonitor.setMonitorThreads(
true
);
lowResourcesMonitor.setMaxConnections(
0
);
lowResourcesMonitor.setMaxMemory(
0
);
lowResourcesMonitor.setMaxLowResourcesTime(
5000
);
server.addBean(lowResourcesMonitor);
// === test-realm.xml ===
HashLoginService login =
new
HashLoginService();
login.setName(
"Test Realm"
);
login.setConfig(jetty_base +
"/etc/realm.properties"
);
login.setRefreshInterval(
0
);
server.addBean(login);
// Start the server
server.start();
server.join();
}
}
|