Eclipse Jetty servlet container providing comprehensive servlet, filter, and listener integration with lifecycle management and dynamic registration support.
—
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.
The ServletHandler is the core component responsible for mapping HTTP requests to servlets and managing servlet instances.
public class ServletHandler extends ScopedHandler {
// Constructor
public ServletHandler();
// Configuration properties
public boolean isEnsureDefaultServlet();
public void setEnsureDefaultServlet(boolean ensureDefaultServlet);
public boolean isStartWithUnavailable();
public void setStartWithUnavailable(boolean startWithUnavailable);
public boolean isFilterChainsCached();
public void setFilterChainsCached(boolean filterChainsCached);
public int getMaxFilterChainsCacheSize();
public void setMaxFilterChainsCacheSize(int maxFilterChainsCacheSize);
public boolean isAllowDuplicateMappings();
public void setAllowDuplicateMappings(boolean allowDuplicateMappings);
// Context access
public ServletContext getServletContext();
// Servlet management
public ServletHolder[] getServlets();
public ServletMapping[] getServletMappings();
public ServletHolder newServletHolder(Source source);
public ServletHolder getServlet(String name);
public void setServlets(ServletHolder[] holders);
public void setServletMappings(ServletMapping[] servletMappings);
// Filter management
public FilterHolder[] getFilters();
public FilterMapping[] getFilterMappings();
public FilterHolder newFilterHolder(Source source);
public FilterHolder getFilter(String name);
public void setFilters(FilterHolder[] holders);
public void setFilterMappings(FilterMapping[] filterMappings);
// Listener management
public ListenerHolder[] getListeners();
public ListenerHolder newListenerHolder(Source source);
public void setListeners(ListenerHolder[] listeners);
// Initialization
public void initialize();
public boolean isInitialized();
}// Add servlet with mapping
public ServletHolder addServletWithMapping(String className, String pathSpec);
public ServletHolder addServletWithMapping(Class<? extends Servlet> servlet, String pathSpec);
public void addServletWithMapping(ServletHolder servlet, String pathSpec);
// Add servlet without mapping
public void addServlet(ServletHolder servletHolder);
// Add servlet mapping
public void addServletMapping(ServletMapping servletMapping);
// Get servlet mapping
public ServletMapping getServletMapping(String pathSpec);// Add filter with mapping
public void addFilterWithMapping(FilterHolder filterHolder, String pathSpec,
EnumSet<DispatcherType> dispatches);
public FilterHolder addFilterWithMapping(Class<? extends Filter> filterClass, String pathSpec,
EnumSet<DispatcherType> dispatches);
public FilterHolder addFilterWithMapping(String className, String pathSpec,
EnumSet<DispatcherType> dispatches);
// Add filter and mapping separately
public void addFilter(FilterHolder filterHolder);
public void addFilterMapping(FilterMapping filterMapping);
public void prependFilterMapping(FilterMapping filterMapping);
public void insertFilterMapping(FilterMapping filterMapping);
// Add listener
public void addListener(ListenerHolder listenerHolder);The ServletHolder manages individual servlet instances, their configuration, and lifecycle.
public class ServletHolder extends Holder<Servlet>
implements UserIdentity.Scope, Comparable<ServletHolder> {
// Constants
public static final String APACHE_SENTINEL_CLASS = "org.apache.tomcat.InstanceManager";
public static final String JSP_GENERATED_PACKAGE_NAME =
"org.eclipse.jetty.servlet.jspPackagePrefix";
// Constructors
public ServletHolder();
public ServletHolder(Source creator);
public ServletHolder(Servlet servlet);
public ServletHolder(String name, Class<? extends Servlet> servlet);
public ServletHolder(String name, Servlet servlet);
public ServletHolder(Class<? extends Servlet> servlet);
// Servlet instance management
public void setServlet(Servlet servlet);
public Servlet getServlet();
// Initialization order
public int getInitOrder();
public void setInitOrder(int order);
// Lifecycle management
public void doStart();
public void initialize();
public void doStop();
public void destroyInstance(Object instance);
// Enable/disable
public boolean isEnabled();
public void setEnabled(boolean enabled);
// Path information
public String getForcedPath();
public void setForcedPath(String forcedPath);
// Security role mapping
public void setUserRoleLink(String name, String link);
public String getUserRoleLink(String name);
// Comparison and equality
public int compareTo(ServletHolder sh);
public boolean equals(Object o);
public int hashCode();
// Unavailable exception handling
public UnavailableException getUnavailableException();
}// Path context methods
public String getContextPath();
public String getServletPath();
public String getPathInfo();
// Security method
public boolean isUserInRole(UserIdentity.Scope scope, UserIdentity userIdentity, String role);public enum JspContainer {
APACHE, OTHER
}The ServletMapping class defines URL pattern to servlet associations.
public class ServletMapping {
// Constructors
public ServletMapping();
public ServletMapping(Source source);
// Path specification management
public String[] getPathSpecs();
public void setPathSpecs(String[] pathSpecs);
public void setPathSpec(String pathSpec);
// Servlet name
public String getServletName();
public void setServletName(String servletName);
// Source tracking
public boolean isFromDefaultDescriptor();
public void setFromDefaultDescriptor(boolean fromDefaultDescriptor);
public Source getSource();
// String representation
public String toString();
}import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlet.ServletMapping;
import jakarta.servlet.http.HttpServlet;
// Create servlet handler
ServletHandler handler = new ServletHandler();
// Method 1: Add servlet with mapping in one call
ServletHolder holder1 = handler.addServletWithMapping(MyServlet.class, "/api/*");
// Method 2: Add servlet and mapping separately
ServletHolder holder2 = new ServletHolder("dataServlet", DataServlet.class);
handler.addServlet(holder2);
ServletMapping mapping = new ServletMapping();
mapping.setServletName("dataServlet");
mapping.setPathSpec("/data/*");
handler.addServletMapping(mapping);
// Method 3: Using class name
ServletHolder holder3 = handler.addServletWithMapping(
"com.example.ConfigServlet", "/config");import org.eclipse.jetty.servlet.ServletHolder;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
// Create servlet holder with configuration
ServletHolder servletHolder = new ServletHolder("myServlet", MyServlet.class);
// Set initialization parameters
servletHolder.setInitParameter("configFile", "/etc/myapp/config.xml");
servletHolder.setInitParameter("debugMode", "true");
servletHolder.setInitParameter("maxConnections", "100");
// Set initialization order (load-on-startup)
servletHolder.setInitOrder(1); // Load early in startup
// Enable/disable servlet
servletHolder.setEnabled(true);
// Set async support
servletHolder.setAsyncSupported(true);
// Force specific path for servlet (rare use case)
servletHolder.setForcedPath("/forced/path");
// Add to handler
handler.addServletWithMapping(servletHolder, "/myservlet/*");import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.Source;
import jakarta.servlet.DispatcherType;
import java.util.EnumSet;
// Create and configure servlet handler
ServletHandler handler = new ServletHandler();
// Configure caching and performance
handler.setFilterChainsCached(true);
handler.setMaxFilterChainsCacheSize(512);
// Allow multiple servlets to map to same path (last wins)
handler.setAllowDuplicateMappings(true);
// Ensure default servlet is present for static content
handler.setEnsureDefaultServlet(true);
// Allow starting even if some servlets are unavailable
handler.setStartWithUnavailable(true);
// Create servlet holders with different sources
ServletHolder embeddedServlet = handler.newServletHolder(Source.EMBEDDED);
embeddedServlet.setHeldClass(MyEmbeddedServlet.class);
embeddedServlet.setName("embedded");
ServletHolder apiServlet = handler.newServletHolder(Source.JAVAX_API);
apiServlet.setClassName("com.example.ApiServlet");
apiServlet.setName("api");
// Add servlets
handler.addServlet(embeddedServlet);
handler.addServlet(apiServlet);
// Create mappings
ServletMapping embeddedMapping = new ServletMapping(Source.EMBEDDED);
embeddedMapping.setServletName("embedded");
embeddedMapping.setPathSpecs(new String[]{"/embedded/*", "/embed"});
ServletMapping apiMapping = new ServletMapping(Source.JAVAX_API);
apiMapping.setServletName("api");
apiMapping.setPathSpec("/api/v1/*");
handler.addServletMapping(embeddedMapping);
handler.addServletMapping(apiMapping);
// Initialize handler
handler.initialize();public class LifecycleAwareServlet extends HttpServlet {
@Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet initialized with parameters:");
Enumeration<String> paramNames = getInitParameterNames();
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
System.out.println(" " + name + " = " + getInitParameter(name));
}
}
@Override
public void destroy() {
System.out.println("Servlet destroyed");
super.destroy();
}
}
// Configure servlet with lifecycle awareness
ServletHolder holder = new ServletHolder("lifecycle", LifecycleAwareServlet.class);
// Set initialization order for predictable startup
holder.setInitOrder(10);
// Start servlet holder (calls servlet.init())
try {
holder.start();
} catch (Exception e) {
System.err.println("Failed to start servlet: " + e.getMessage());
}
// Check servlet status
if (holder.isStarted() && holder.isEnabled()) {
System.out.println("Servlet is ready to handle requests");
}
// Get servlet instance (creates if needed)
Servlet servlet = holder.getServlet();
// Stop servlet holder (calls servlet.destroy())
try {
holder.stop();
} catch (Exception e) {
System.err.println("Failed to stop servlet: " + e.getMessage());
}import jakarta.servlet.UnavailableException;
// Check for unavailable servlets
for (ServletHolder holder : handler.getServlets()) {
UnavailableException unavailable = holder.getUnavailableException();
if (unavailable != null) {
System.err.println("Servlet " + holder.getName() + " is unavailable: " +
unavailable.getMessage());
if (unavailable.isPermanent()) {
System.err.println(" Permanent unavailability");
} else {
int seconds = unavailable.getUnavailableSeconds();
System.err.println(" Temporarily unavailable for " + seconds + " seconds");
}
}
}
// Enable unavailable servlets to start anyway
handler.setStartWithUnavailable(true);// Configure security role mapping in servlet
ServletHolder secureHolder = new ServletHolder("secure", SecureServlet.class);
// Map application roles to security roles
secureHolder.setUserRoleLink("admin", "administrator");
secureHolder.setUserRoleLink("user", "standard-user");
secureHolder.setUserRoleLink("guest", "anonymous");
// The servlet can then use these mapped roles
public class SecureServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
if (req.isUserInRole("admin")) {
// Administrator functionality
} else if (req.isUserInRole("user")) {
// Standard user functionality
} else {
resp.sendError(403, "Access denied");
}
}
}// Single servlet handling multiple path patterns
ServletHolder multiPathServlet = new ServletHolder("multiPath", MultiPathServlet.class);
handler.addServlet(multiPathServlet);
// Create mapping with multiple path specifications
ServletMapping mapping = new ServletMapping();
mapping.setServletName("multiPath");
mapping.setPathSpecs(new String[]{
"/api/v1/*", // RESTful API
"/api/v2/*", // Version 2 API
"/legacy/*", // Legacy compatibility
"*.json" // All JSON requests
});
handler.addServletMapping(mapping);
// Servlet can determine which path was matched
public class MultiPathServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
String servletPath = req.getServletPath();
String pathInfo = req.getPathInfo();
if (servletPath.startsWith("/api/v1")) {
handleV1Request(req, resp);
} else if (servletPath.startsWith("/api/v2")) {
handleV2Request(req, resp);
} else if (servletPath.startsWith("/legacy")) {
handleLegacyRequest(req, resp);
} else if (servletPath.endsWith(".json")) {
handleJsonRequest(req, resp);
}
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-eclipse-jetty--jetty-servlet