0
# Servlet Handling
1
2
Servlet handling in Eclipse Jetty provides comprehensive servlet lifecycle management, URL pattern mapping, initialization ordering, and dynamic registration capabilities through the ServletHandler and ServletHolder classes.
3
4
## ServletHandler
5
6
The `ServletHandler` is the core component responsible for mapping HTTP requests to servlets and managing servlet instances.
7
8
```java { .api }
9
public class ServletHandler extends ScopedHandler {
10
// Constructor
11
public ServletHandler();
12
13
// Configuration properties
14
public boolean isEnsureDefaultServlet();
15
public void setEnsureDefaultServlet(boolean ensureDefaultServlet);
16
public boolean isStartWithUnavailable();
17
public void setStartWithUnavailable(boolean startWithUnavailable);
18
public boolean isFilterChainsCached();
19
public void setFilterChainsCached(boolean filterChainsCached);
20
public int getMaxFilterChainsCacheSize();
21
public void setMaxFilterChainsCacheSize(int maxFilterChainsCacheSize);
22
public boolean isAllowDuplicateMappings();
23
public void setAllowDuplicateMappings(boolean allowDuplicateMappings);
24
25
// Context access
26
public ServletContext getServletContext();
27
28
// Servlet management
29
public ServletHolder[] getServlets();
30
public ServletMapping[] getServletMappings();
31
public ServletHolder newServletHolder(Source source);
32
public ServletHolder getServlet(String name);
33
public void setServlets(ServletHolder[] holders);
34
public void setServletMappings(ServletMapping[] servletMappings);
35
36
// Filter management
37
public FilterHolder[] getFilters();
38
public FilterMapping[] getFilterMappings();
39
public FilterHolder newFilterHolder(Source source);
40
public FilterHolder getFilter(String name);
41
public void setFilters(FilterHolder[] holders);
42
public void setFilterMappings(FilterMapping[] filterMappings);
43
44
// Listener management
45
public ListenerHolder[] getListeners();
46
public ListenerHolder newListenerHolder(Source source);
47
public void setListeners(ListenerHolder[] listeners);
48
49
// Initialization
50
public void initialize();
51
public boolean isInitialized();
52
}
53
```
54
55
### Servlet Registration and Management
56
57
```java { .api }
58
// Add servlet with mapping
59
public ServletHolder addServletWithMapping(String className, String pathSpec);
60
public ServletHolder addServletWithMapping(Class<? extends Servlet> servlet, String pathSpec);
61
public void addServletWithMapping(ServletHolder servlet, String pathSpec);
62
63
// Add servlet without mapping
64
public void addServlet(ServletHolder servletHolder);
65
66
// Add servlet mapping
67
public void addServletMapping(ServletMapping servletMapping);
68
69
// Get servlet mapping
70
public ServletMapping getServletMapping(String pathSpec);
71
```
72
73
### Filter Integration
74
75
```java { .api }
76
// Add filter with mapping
77
public void addFilterWithMapping(FilterHolder filterHolder, String pathSpec,
78
EnumSet<DispatcherType> dispatches);
79
public FilterHolder addFilterWithMapping(Class<? extends Filter> filterClass, String pathSpec,
80
EnumSet<DispatcherType> dispatches);
81
public FilterHolder addFilterWithMapping(String className, String pathSpec,
82
EnumSet<DispatcherType> dispatches);
83
84
// Add filter and mapping separately
85
public void addFilter(FilterHolder filterHolder);
86
public void addFilterMapping(FilterMapping filterMapping);
87
public void prependFilterMapping(FilterMapping filterMapping);
88
public void insertFilterMapping(FilterMapping filterMapping);
89
90
// Add listener
91
public void addListener(ListenerHolder listenerHolder);
92
```
93
94
## ServletHolder
95
96
The `ServletHolder` manages individual servlet instances, their configuration, and lifecycle.
97
98
```java { .api }
99
public class ServletHolder extends Holder<Servlet>
100
implements UserIdentity.Scope, Comparable<ServletHolder> {
101
102
// Constants
103
public static final String APACHE_SENTINEL_CLASS = "org.apache.tomcat.InstanceManager";
104
public static final String JSP_GENERATED_PACKAGE_NAME =
105
"org.eclipse.jetty.servlet.jspPackagePrefix";
106
107
// Constructors
108
public ServletHolder();
109
public ServletHolder(Source creator);
110
public ServletHolder(Servlet servlet);
111
public ServletHolder(String name, Class<? extends Servlet> servlet);
112
public ServletHolder(String name, Servlet servlet);
113
public ServletHolder(Class<? extends Servlet> servlet);
114
115
// Servlet instance management
116
public void setServlet(Servlet servlet);
117
public Servlet getServlet();
118
119
// Initialization order
120
public int getInitOrder();
121
public void setInitOrder(int order);
122
123
// Lifecycle management
124
public void doStart();
125
public void initialize();
126
public void doStop();
127
public void destroyInstance(Object instance);
128
129
// Enable/disable
130
public boolean isEnabled();
131
public void setEnabled(boolean enabled);
132
133
// Path information
134
public String getForcedPath();
135
public void setForcedPath(String forcedPath);
136
137
// Security role mapping
138
public void setUserRoleLink(String name, String link);
139
public String getUserRoleLink(String name);
140
141
// Comparison and equality
142
public int compareTo(ServletHolder sh);
143
public boolean equals(Object o);
144
public int hashCode();
145
146
// Unavailable exception handling
147
public UnavailableException getUnavailableException();
148
}
149
```
150
151
### UserIdentity.Scope Implementation
152
153
```java { .api }
154
// Path context methods
155
public String getContextPath();
156
public String getServletPath();
157
public String getPathInfo();
158
159
// Security method
160
public boolean isUserInRole(UserIdentity.Scope scope, UserIdentity userIdentity, String role);
161
```
162
163
### JSP Container Detection
164
165
```java { .api }
166
public enum JspContainer {
167
APACHE, OTHER
168
}
169
```
170
171
## ServletMapping
172
173
The `ServletMapping` class defines URL pattern to servlet associations.
174
175
```java { .api }
176
public class ServletMapping {
177
// Constructors
178
public ServletMapping();
179
public ServletMapping(Source source);
180
181
// Path specification management
182
public String[] getPathSpecs();
183
public void setPathSpecs(String[] pathSpecs);
184
public void setPathSpec(String pathSpec);
185
186
// Servlet name
187
public String getServletName();
188
public void setServletName(String servletName);
189
190
// Source tracking
191
public boolean isFromDefaultDescriptor();
192
public void setFromDefaultDescriptor(boolean fromDefaultDescriptor);
193
public Source getSource();
194
195
// String representation
196
public String toString();
197
}
198
```
199
200
## Usage Examples
201
202
### Basic Servlet Registration
203
204
```java
205
import org.eclipse.jetty.servlet.ServletHandler;
206
import org.eclipse.jetty.servlet.ServletHolder;
207
import org.eclipse.jetty.servlet.ServletMapping;
208
import jakarta.servlet.http.HttpServlet;
209
210
// Create servlet handler
211
ServletHandler handler = new ServletHandler();
212
213
// Method 1: Add servlet with mapping in one call
214
ServletHolder holder1 = handler.addServletWithMapping(MyServlet.class, "/api/*");
215
216
// Method 2: Add servlet and mapping separately
217
ServletHolder holder2 = new ServletHolder("dataServlet", DataServlet.class);
218
handler.addServlet(holder2);
219
220
ServletMapping mapping = new ServletMapping();
221
mapping.setServletName("dataServlet");
222
mapping.setPathSpec("/data/*");
223
handler.addServletMapping(mapping);
224
225
// Method 3: Using class name
226
ServletHolder holder3 = handler.addServletWithMapping(
227
"com.example.ConfigServlet", "/config");
228
```
229
230
### Servlet Configuration and Initialization
231
232
```java
233
import org.eclipse.jetty.servlet.ServletHolder;
234
import jakarta.servlet.ServletException;
235
import jakarta.servlet.http.HttpServlet;
236
237
// Create servlet holder with configuration
238
ServletHolder servletHolder = new ServletHolder("myServlet", MyServlet.class);
239
240
// Set initialization parameters
241
servletHolder.setInitParameter("configFile", "/etc/myapp/config.xml");
242
servletHolder.setInitParameter("debugMode", "true");
243
servletHolder.setInitParameter("maxConnections", "100");
244
245
// Set initialization order (load-on-startup)
246
servletHolder.setInitOrder(1); // Load early in startup
247
248
// Enable/disable servlet
249
servletHolder.setEnabled(true);
250
251
// Set async support
252
servletHolder.setAsyncSupported(true);
253
254
// Force specific path for servlet (rare use case)
255
servletHolder.setForcedPath("/forced/path");
256
257
// Add to handler
258
handler.addServletWithMapping(servletHolder, "/myservlet/*");
259
```
260
261
### Advanced Servlet Handler Configuration
262
263
```java
264
import org.eclipse.jetty.servlet.ServletHandler;
265
import org.eclipse.jetty.servlet.Source;
266
import jakarta.servlet.DispatcherType;
267
import java.util.EnumSet;
268
269
// Create and configure servlet handler
270
ServletHandler handler = new ServletHandler();
271
272
// Configure caching and performance
273
handler.setFilterChainsCached(true);
274
handler.setMaxFilterChainsCacheSize(512);
275
276
// Allow multiple servlets to map to same path (last wins)
277
handler.setAllowDuplicateMappings(true);
278
279
// Ensure default servlet is present for static content
280
handler.setEnsureDefaultServlet(true);
281
282
// Allow starting even if some servlets are unavailable
283
handler.setStartWithUnavailable(true);
284
285
// Create servlet holders with different sources
286
ServletHolder embeddedServlet = handler.newServletHolder(Source.EMBEDDED);
287
embeddedServlet.setHeldClass(MyEmbeddedServlet.class);
288
embeddedServlet.setName("embedded");
289
290
ServletHolder apiServlet = handler.newServletHolder(Source.JAVAX_API);
291
apiServlet.setClassName("com.example.ApiServlet");
292
apiServlet.setName("api");
293
294
// Add servlets
295
handler.addServlet(embeddedServlet);
296
handler.addServlet(apiServlet);
297
298
// Create mappings
299
ServletMapping embeddedMapping = new ServletMapping(Source.EMBEDDED);
300
embeddedMapping.setServletName("embedded");
301
embeddedMapping.setPathSpecs(new String[]{"/embedded/*", "/embed"});
302
303
ServletMapping apiMapping = new ServletMapping(Source.JAVAX_API);
304
apiMapping.setServletName("api");
305
apiMapping.setPathSpec("/api/v1/*");
306
307
handler.addServletMapping(embeddedMapping);
308
handler.addServletMapping(apiMapping);
309
310
// Initialize handler
311
handler.initialize();
312
```
313
314
### Servlet Lifecycle Management
315
316
```java
317
public class LifecycleAwareServlet extends HttpServlet {
318
@Override
319
public void init() throws ServletException {
320
super.init();
321
System.out.println("Servlet initialized with parameters:");
322
Enumeration<String> paramNames = getInitParameterNames();
323
while (paramNames.hasMoreElements()) {
324
String name = paramNames.nextElement();
325
System.out.println(" " + name + " = " + getInitParameter(name));
326
}
327
}
328
329
@Override
330
public void destroy() {
331
System.out.println("Servlet destroyed");
332
super.destroy();
333
}
334
}
335
336
// Configure servlet with lifecycle awareness
337
ServletHolder holder = new ServletHolder("lifecycle", LifecycleAwareServlet.class);
338
339
// Set initialization order for predictable startup
340
holder.setInitOrder(10);
341
342
// Start servlet holder (calls servlet.init())
343
try {
344
holder.start();
345
} catch (Exception e) {
346
System.err.println("Failed to start servlet: " + e.getMessage());
347
}
348
349
// Check servlet status
350
if (holder.isStarted() && holder.isEnabled()) {
351
System.out.println("Servlet is ready to handle requests");
352
}
353
354
// Get servlet instance (creates if needed)
355
Servlet servlet = holder.getServlet();
356
357
// Stop servlet holder (calls servlet.destroy())
358
try {
359
holder.stop();
360
} catch (Exception e) {
361
System.err.println("Failed to stop servlet: " + e.getMessage());
362
}
363
```
364
365
### Error Handling and Unavailable Servlets
366
367
```java
368
import jakarta.servlet.UnavailableException;
369
370
// Check for unavailable servlets
371
for (ServletHolder holder : handler.getServlets()) {
372
UnavailableException unavailable = holder.getUnavailableException();
373
if (unavailable != null) {
374
System.err.println("Servlet " + holder.getName() + " is unavailable: " +
375
unavailable.getMessage());
376
377
if (unavailable.isPermanent()) {
378
System.err.println(" Permanent unavailability");
379
} else {
380
int seconds = unavailable.getUnavailableSeconds();
381
System.err.println(" Temporarily unavailable for " + seconds + " seconds");
382
}
383
}
384
}
385
386
// Enable unavailable servlets to start anyway
387
handler.setStartWithUnavailable(true);
388
```
389
390
### Security Role Integration
391
392
```java
393
// Configure security role mapping in servlet
394
ServletHolder secureHolder = new ServletHolder("secure", SecureServlet.class);
395
396
// Map application roles to security roles
397
secureHolder.setUserRoleLink("admin", "administrator");
398
secureHolder.setUserRoleLink("user", "standard-user");
399
secureHolder.setUserRoleLink("guest", "anonymous");
400
401
// The servlet can then use these mapped roles
402
public class SecureServlet extends HttpServlet {
403
@Override
404
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
405
if (req.isUserInRole("admin")) {
406
// Administrator functionality
407
} else if (req.isUserInRole("user")) {
408
// Standard user functionality
409
} else {
410
resp.sendError(403, "Access denied");
411
}
412
}
413
}
414
```
415
416
### Multi-Path Servlet Mapping
417
418
```java
419
// Single servlet handling multiple path patterns
420
ServletHolder multiPathServlet = new ServletHolder("multiPath", MultiPathServlet.class);
421
handler.addServlet(multiPathServlet);
422
423
// Create mapping with multiple path specifications
424
ServletMapping mapping = new ServletMapping();
425
mapping.setServletName("multiPath");
426
mapping.setPathSpecs(new String[]{
427
"/api/v1/*", // RESTful API
428
"/api/v2/*", // Version 2 API
429
"/legacy/*", // Legacy compatibility
430
"*.json" // All JSON requests
431
});
432
433
handler.addServletMapping(mapping);
434
435
// Servlet can determine which path was matched
436
public class MultiPathServlet extends HttpServlet {
437
@Override
438
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
439
String servletPath = req.getServletPath();
440
String pathInfo = req.getPathInfo();
441
442
if (servletPath.startsWith("/api/v1")) {
443
handleV1Request(req, resp);
444
} else if (servletPath.startsWith("/api/v2")) {
445
handleV2Request(req, resp);
446
} else if (servletPath.startsWith("/legacy")) {
447
handleLegacyRequest(req, resp);
448
} else if (servletPath.endsWith(".json")) {
449
handleJsonRequest(req, resp);
450
}
451
}
452
}
453
```