Embedded Apache Tomcat servlet container with Jakarta Servlet API, HTTP connectors, and lifecycle management for Java web applications
Complete implementation of Jakarta Servlet 6.0 specification providing the foundation for Java web application development. This includes servlet lifecycle management, request/response handling, filters, listeners, sessions, async processing, security constraints, and multipart file uploads.
The fundamental servlet API for handling HTTP requests and responses.
// Base servlet interface
public interface Servlet {
void init(ServletConfig config) throws ServletException;
void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
void destroy();
ServletConfig getServletConfig();
String getServletInfo();
}
// Servlet configuration
public interface ServletConfig {
String getServletName();
ServletContext getServletContext();
String getInitParameter(String name);
Enumeration<String> getInitParameterNames();
}
// Generic servlet base class
public abstract class GenericServlet implements Servlet, ServletConfig {
public GenericServlet();
public void destroy();
public String getInitParameter(String name);
public Enumeration<String> getInitParameterNames();
public ServletConfig getServletConfig();
public ServletContext getServletContext();
public String getServletInfo();
public void init(ServletConfig config) throws ServletException;
public void init() throws ServletException;
public void log(String message);
public void log(String message, Throwable t);
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
public String getServletName();
}HTTP-specific servlet implementation extending GenericServlet for web applications.
public abstract class HttpServlet extends GenericServlet {
public static final String LEGACY_DO_HEAD = "jakarta.servlet.http.legacyDoHead";
public HttpServlet();
// HTTP method handlers
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected long getLastModified(HttpServletRequest req);
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
}Interfaces for accessing request data and generating responses.
// Generic servlet request
public interface ServletRequest {
Object getAttribute(String name);
Enumeration<String> getAttributeNames();
String getCharacterEncoding();
void setCharacterEncoding(String encoding) throws UnsupportedEncodingException;
int getContentLength();
long getContentLengthLong();
String getContentType();
ServletInputStream getInputStream() throws IOException;
String getParameter(String name);
Enumeration<String> getParameterNames();
String[] getParameterValues(String name);
Map<String,String[]> getParameterMap();
String getProtocol();
String getScheme();
String getServerName();
int getServerPort();
BufferedReader getReader() throws IOException;
String getRemoteAddr();
String getRemoteHost();
void setAttribute(String name, Object o);
void removeAttribute(String name);
Locale getLocale();
Enumeration<Locale> getLocales();
boolean isSecure();
RequestDispatcher getRequestDispatcher(String path);
int getRemotePort();
String getLocalName();
String getLocalAddr();
int getLocalPort();
ServletContext getServletContext();
AsyncContext startAsync() throws IllegalStateException;
AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
throws IllegalStateException;
boolean isAsyncStarted();
boolean isAsyncSupported();
AsyncContext getAsyncContext();
DispatcherType getDispatcherType();
String getRequestId();
String getProtocolRequestId();
ServletConnection getServletConnection();
}
// Generic servlet response
public interface ServletResponse {
String getCharacterEncoding();
String getContentType();
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
void setCharacterEncoding(String charset);
void setContentLength(int len);
void setContentLengthLong(long length);
void setContentType(String type);
void setBufferSize(int size);
int getBufferSize();
void flushBuffer() throws IOException;
void resetBuffer();
boolean isCommitted();
void reset();
void setLocale(Locale loc);
Locale getLocale();
}HTTP-specific extensions with cookies, headers, sessions, and redirects.
public interface HttpServletRequest extends ServletRequest {
// Authentication
String getAuthType();
String getRemoteUser();
boolean isUserInRole(String role);
Principal getUserPrincipal();
boolean authenticate(HttpServletResponse response) throws IOException, ServletException;
void login(String username, String password) throws ServletException;
void logout() throws ServletException;
// Cookies
Cookie[] getCookies();
// Headers
long getDateHeader(String name);
String getHeader(String name);
Enumeration<String> getHeaders(String name);
Enumeration<String> getHeaderNames();
int getIntHeader(String name);
// HTTP method and path
String getMethod();
String getPathInfo();
String getPathTranslated();
String getContextPath();
String getQueryString();
String getRequestURI();
StringBuffer getRequestURL();
String getServletPath();
HttpServletMapping getHttpServletMapping();
// Sessions
HttpSession getSession(boolean create);
HttpSession getSession();
String getRequestedSessionId();
boolean isRequestedSessionIdValid();
boolean isRequestedSessionIdFromCookie();
boolean isRequestedSessionIdFromURL();
String changeSessionId();
// Multipart
Collection<Part> getParts() throws IOException, ServletException;
Part getPart(String name) throws IOException, ServletException;
// HTTP/2 features
PushBuilder newPushBuilder();
Map<String,String> getTrailerFields();
boolean isTrailerFieldsReady();
// Protocol upgrade
<T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass)
throws IOException, ServletException;
}
public interface HttpServletResponse extends ServletResponse {
// Status codes (constants omitted for brevity)
int SC_CONTINUE = 100;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_INTERNAL_SERVER_ERROR = 500;
// ... more status code constants
// Cookies
void addCookie(Cookie cookie);
// Headers
boolean containsHeader(String name);
String encodeURL(String url);
String encodeRedirectURL(String url);
void sendError(int sc, String msg) throws IOException;
void sendError(int sc) throws IOException;
void sendRedirect(String location) throws IOException;
void setDateHeader(String name, long date);
void addDateHeader(String name, long date);
void setHeader(String name, String value);
void addHeader(String name, String value);
void setIntHeader(String name, int value);
void addIntHeader(String name, int value);
void setStatus(int sc);
int getStatus();
String getHeader(String name);
Collection<String> getHeaders(String name);
Collection<String> getHeaderNames();
// HTTP/2 trailers
void setTrailerFields(Supplier<Map<String,String>> supplier);
Supplier<Map<String,String>> getTrailerFields();
// Early hints (HTTP 103)
void sendEarlyHints();
}Convenience classes for implementing the decorator pattern with servlet requests and responses. These wrapper classes delegate all method calls to the wrapped object, allowing developers to override only specific methods.
/**
* Wrapper for ServletRequest that delegates all method calls to the wrapped request.
* Extend this class and override specific methods to customize request behavior.
*/
public class ServletRequestWrapper implements ServletRequest {
public ServletRequestWrapper(ServletRequest request);
public ServletRequest getRequest();
public void setRequest(ServletRequest request);
// All ServletRequest methods delegate to wrapped request
@Override
public Object getAttribute(String name);
@Override
public Enumeration<String> getAttributeNames();
@Override
public String getCharacterEncoding();
@Override
public void setCharacterEncoding(String env) throws UnsupportedEncodingException;
@Override
public int getContentLength();
@Override
public long getContentLengthLong();
@Override
public String getContentType();
@Override
public ServletInputStream getInputStream() throws IOException;
@Override
public String getParameter(String name);
@Override
public Map<String,String[]> getParameterMap();
@Override
public Enumeration<String> getParameterNames();
@Override
public String[] getParameterValues(String name);
@Override
public String getProtocol();
@Override
public String getScheme();
@Override
public String getServerName();
@Override
public int getServerPort();
@Override
public BufferedReader getReader() throws IOException;
@Override
public String getRemoteAddr();
@Override
public String getRemoteHost();
@Override
public void setAttribute(String name, Object o);
@Override
public void removeAttribute(String name);
@Override
public Locale getLocale();
@Override
public Enumeration<Locale> getLocales();
@Override
public boolean isSecure();
@Override
public RequestDispatcher getRequestDispatcher(String path);
@Override
public int getRemotePort();
@Override
public String getLocalName();
@Override
public String getLocalAddr();
@Override
public int getLocalPort();
@Override
public ServletContext getServletContext();
@Override
public AsyncContext startAsync() throws IllegalStateException;
@Override
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
throws IllegalStateException;
@Override
public boolean isAsyncStarted();
@Override
public boolean isAsyncSupported();
@Override
public AsyncContext getAsyncContext();
@Override
public DispatcherType getDispatcherType();
@Override
public String getRequestId();
@Override
public String getProtocolRequestId();
@Override
public ServletConnection getServletConnection();
}
/**
* Wrapper for HttpServletRequest that delegates all method calls to the wrapped request.
* Extends ServletRequestWrapper and adds HTTP-specific delegation.
*/
public class HttpServletRequestWrapper extends ServletRequestWrapper implements HttpServletRequest {
public HttpServletRequestWrapper(HttpServletRequest request);
// All HttpServletRequest methods delegate to wrapped HTTP request
@Override
public String getAuthType();
@Override
public Cookie[] getCookies();
@Override
public long getDateHeader(String name);
@Override
public String getHeader(String name);
@Override
public Enumeration<String> getHeaders(String name);
@Override
public Enumeration<String> getHeaderNames();
@Override
public int getIntHeader(String name);
@Override
public HttpServletMapping getHttpServletMapping();
@Override
public String getMethod();
@Override
public String getPathInfo();
@Override
public String getPathTranslated();
@Override
public String getContextPath();
@Override
public String getQueryString();
@Override
public String getRemoteUser();
@Override
public boolean isUserInRole(String role);
@Override
public Principal getUserPrincipal();
@Override
public String getRequestedSessionId();
@Override
public String getRequestURI();
@Override
public StringBuffer getRequestURL();
@Override
public String getServletPath();
@Override
public HttpSession getSession(boolean create);
@Override
public HttpSession getSession();
@Override
public String changeSessionId();
@Override
public boolean isRequestedSessionIdValid();
@Override
public boolean isRequestedSessionIdFromCookie();
@Override
public boolean isRequestedSessionIdFromURL();
@Override
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException;
@Override
public void login(String username, String password) throws ServletException;
@Override
public void logout() throws ServletException;
@Override
public Collection<Part> getParts() throws IOException, ServletException;
@Override
public Part getPart(String name) throws IOException, ServletException;
@Override
public <T extends HttpUpgradeHandler> T upgrade(Class<T> httpUpgradeHandlerClass)
throws IOException, ServletException;
@Override
public PushBuilder newPushBuilder();
@Override
public Map<String,String> getTrailerFields();
@Override
public boolean isTrailerFieldsReady();
}
/**
* Wrapper for ServletResponse that delegates all method calls to the wrapped response.
* Extend this class and override specific methods to customize response behavior.
*/
public class ServletResponseWrapper implements ServletResponse {
public ServletResponseWrapper(ServletResponse response);
public ServletResponse getResponse();
public void setResponse(ServletResponse response);
// All ServletResponse methods delegate to wrapped response
@Override
public String getCharacterEncoding();
@Override
public String getContentType();
@Override
public ServletOutputStream getOutputStream() throws IOException;
@Override
public PrintWriter getWriter() throws IOException;
@Override
public void setCharacterEncoding(String charset);
@Override
public void setContentLength(int len);
@Override
public void setContentLengthLong(long len);
@Override
public void setContentType(String type);
@Override
public void setBufferSize(int size);
@Override
public int getBufferSize();
@Override
public void flushBuffer() throws IOException;
@Override
public void resetBuffer();
@Override
public boolean isCommitted();
@Override
public void reset();
@Override
public void setLocale(Locale loc);
@Override
public Locale getLocale();
}
/**
* Wrapper for HttpServletResponse that delegates all method calls to the wrapped response.
* Extends ServletResponseWrapper and adds HTTP-specific delegation.
*/
public class HttpServletResponseWrapper extends ServletResponseWrapper implements HttpServletResponse {
public HttpServletResponseWrapper(HttpServletResponse response);
// All HttpServletResponse methods delegate to wrapped HTTP response
@Override
public void addCookie(Cookie cookie);
@Override
public boolean containsHeader(String name);
@Override
public String encodeURL(String url);
@Override
public String encodeRedirectURL(String url);
@Override
public void sendError(int sc, String msg) throws IOException;
@Override
public void sendError(int sc) throws IOException;
@Override
public void sendRedirect(String location) throws IOException;
@Override
public void setDateHeader(String name, long date);
@Override
public void addDateHeader(String name, long date);
@Override
public void setHeader(String name, String value);
@Override
public void addHeader(String name, String value);
@Override
public void setIntHeader(String name, int value);
@Override
public void addIntHeader(String name, int value);
@Override
public void setStatus(int sc);
@Override
public int getStatus();
@Override
public String getHeader(String name);
@Override
public Collection<String> getHeaders(String name);
@Override
public Collection<String> getHeaderNames();
@Override
public void setTrailerFields(Supplier<Map<String,String>> supplier);
@Override
public Supplier<Map<String,String>> getTrailerFields();
@Override
public void sendEarlyHints();
}Usage Example:
public class LoggingRequestWrapper extends HttpServletRequestWrapper {
private static final Logger logger = Logger.getLogger(LoggingRequestWrapper.class.getName());
public LoggingRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
logger.info("Parameter '" + name + "' = '" + value + "'");
return value;
}
}
// In a filter:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
LoggingRequestWrapper wrapper = new LoggingRequestWrapper(httpRequest);
chain.doFilter(wrapper, response);
}Web application context providing access to resources, configuration, and container services.
public interface ServletContext {
// Context information
String getContextPath();
int getMajorVersion();
int getMinorVersion();
int getEffectiveMajorVersion();
int getEffectiveMinorVersion();
String getMimeType(String file);
Set<String> getResourcePaths(String path);
URL getResource(String path) throws MalformedURLException;
InputStream getResourceAsStream(String path);
RequestDispatcher getRequestDispatcher(String path);
RequestDispatcher getNamedDispatcher(String name);
String getRealPath(String path);
String getServerInfo();
String getServletContextName();
// Initialization parameters
String getInitParameter(String name);
Enumeration<String> getInitParameterNames();
boolean setInitParameter(String name, String value);
// Attributes
Object getAttribute(String name);
Enumeration<String> getAttributeNames();
void setAttribute(String name, Object object);
void removeAttribute(String name);
// Logging
void log(String msg);
void log(String message, Throwable throwable);
// Dynamic registration
ServletRegistration.Dynamic addServlet(String servletName, String className);
ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet);
ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass);
<T extends Servlet> T createServlet(Class<T> clazz) throws ServletException;
ServletRegistration getServletRegistration(String servletName);
Map<String,? extends ServletRegistration> getServletRegistrations();
FilterRegistration.Dynamic addFilter(String filterName, String className);
FilterRegistration.Dynamic addFilter(String filterName, Filter filter);
FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass);
<T extends Filter> T createFilter(Class<T> clazz) throws ServletException;
FilterRegistration getFilterRegistration(String filterName);
Map<String,? extends FilterRegistration> getFilterRegistrations();
void addListener(String className);
<T extends EventListener> void addListener(T t);
void addListener(Class<? extends EventListener> listenerClass);
<T extends EventListener> T createListener(Class<T> clazz) throws ServletException;
// Session configuration
SessionCookieConfig getSessionCookieConfig();
void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes);
Set<SessionTrackingMode> getDefaultSessionTrackingModes();
Set<SessionTrackingMode> getEffectiveSessionTrackingModes();
// Security
void declareRoles(String... roleNames);
// Virtual server name
String getVirtualServerName();
// Session timeout
int getSessionTimeout();
void setSessionTimeout(int sessionTimeout);
// Request/response character encoding
String getRequestCharacterEncoding();
void setRequestCharacterEncoding(String encoding);
String getResponseCharacterEncoding();
void setResponseCharacterEncoding(String encoding);
// Additional context methods
ServletContext getContext(String uripath);
ClassLoader getClassLoader();
JspConfigDescriptor getJspConfigDescriptor();
ServletRegistration.Dynamic addJspFile(String jspName, String jspFile);
}HTTP session management for maintaining user state across requests.
public interface HttpSession {
long getCreationTime();
String getId();
long getLastAccessedTime();
ServletContext getServletContext();
void setMaxInactiveInterval(int interval);
int getMaxInactiveInterval();
Object getAttribute(String name);
Enumeration<String> getAttributeNames();
void setAttribute(String name, Object value);
void removeAttribute(String name);
void invalidate();
boolean isNew();
}
public interface SessionCookieConfig {
void setName(String name);
String getName();
void setDomain(String domain);
String getDomain();
void setPath(String path);
String getPath();
void setComment(String comment);
String getComment();
void setHttpOnly(boolean httpOnly);
boolean isHttpOnly();
void setSecure(boolean secure);
boolean isSecure();
void setMaxAge(int MaxAge);
int getMaxAge();
void setAttribute(String name, String value);
String getAttribute(String name);
Map<String,String> getAttributes();
}
public enum SessionTrackingMode {
COOKIE,
URL,
SSL
}Request/response filtering for cross-cutting concerns.
public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {}
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
default void destroy() {}
}
public interface FilterConfig {
String getFilterName();
ServletContext getServletContext();
String getInitParameter(String name);
Enumeration<String> getInitParameterNames();
}
public interface FilterChain {
void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException;
}
public abstract class GenericFilter implements Filter, FilterConfig {
public String getInitParameter(String name);
public Enumeration<String> getInitParameterNames();
public FilterConfig getFilterConfig();
public ServletContext getServletContext();
public void init(FilterConfig filterConfig) throws ServletException;
public void init() throws ServletException;
public String getFilterName();
}
public abstract class HttpFilter extends GenericFilter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
protected void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException;
}Event listeners for servlet lifecycle, context, session, and request events.
// Context listeners
public interface ServletContextListener extends EventListener {
default void contextInitialized(ServletContextEvent sce) {}
default void contextDestroyed(ServletContextEvent sce) {}
}
public interface ServletContextAttributeListener extends EventListener {
default void attributeAdded(ServletContextAttributeEvent event) {}
default void attributeRemoved(ServletContextAttributeEvent event) {}
default void attributeReplaced(ServletContextAttributeEvent event) {}
}
// Session listeners
public interface HttpSessionListener extends EventListener {
default void sessionCreated(HttpSessionEvent se) {}
default void sessionDestroyed(HttpSessionEvent se) {}
}
public interface HttpSessionAttributeListener extends EventListener {
default void attributeAdded(HttpSessionBindingEvent event) {}
default void attributeRemoved(HttpSessionBindingEvent event) {}
default void attributeReplaced(HttpSessionBindingEvent event) {}
}
public interface HttpSessionIdListener extends EventListener {
void sessionIdChanged(HttpSessionEvent event, String oldSessionId);
}
public interface HttpSessionActivationListener extends EventListener {
default void sessionWillPassivate(HttpSessionEvent se) {}
default void sessionDidActivate(HttpSessionEvent se) {}
}
public interface HttpSessionBindingListener extends EventListener {
default void valueBound(HttpSessionBindingEvent event) {}
default void valueUnbound(HttpSessionBindingEvent event) {}
}
// Request listeners
public interface ServletRequestListener extends EventListener {
default void requestInitialized(ServletRequestEvent sre) {}
default void requestDestroyed(ServletRequestEvent sre) {}
}
public interface ServletRequestAttributeListener extends EventListener {
default void attributeAdded(ServletRequestAttributeEvent srae) {}
default void attributeRemoved(ServletRequestAttributeEvent srae) {}
default void attributeReplaced(ServletRequestAttributeEvent srae) {}
}Non-blocking request processing for improved scalability.
public interface AsyncContext {
static final String ASYNC_REQUEST_URI = "jakarta.servlet.async.request_uri";
static final String ASYNC_CONTEXT_PATH = "jakarta.servlet.async.context_path";
static final String ASYNC_PATH_INFO = "jakarta.servlet.async.path_info";
static final String ASYNC_SERVLET_PATH = "jakarta.servlet.async.servlet_path";
static final String ASYNC_QUERY_STRING = "jakarta.servlet.async.query_string";
static final String ASYNC_MAPPING = "jakarta.servlet.async.mapping";
ServletRequest getRequest();
ServletResponse getResponse();
boolean hasOriginalRequestAndResponse();
void dispatch();
void dispatch(String path);
void dispatch(ServletContext context, String path);
void complete();
void start(Runnable run);
void addListener(AsyncListener listener);
void addListener(AsyncListener listener, ServletRequest servletRequest,
ServletResponse servletResponse);
<T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException;
void setTimeout(long timeout);
long getTimeout();
}
public interface AsyncListener extends EventListener {
void onComplete(AsyncEvent event) throws IOException;
void onTimeout(AsyncEvent event) throws IOException;
void onError(AsyncEvent event) throws IOException;
void onStartAsync(AsyncEvent event) throws IOException;
}
public class AsyncEvent {
public AsyncEvent(AsyncContext context);
public AsyncEvent(AsyncContext context, ServletRequest request, ServletResponse response);
public AsyncEvent(AsyncContext context, Throwable throwable);
public AsyncEvent(AsyncContext context, ServletRequest request, ServletResponse response,
Throwable throwable);
public AsyncContext getAsyncContext();
public ServletRequest getSuppliedRequest();
public ServletResponse getSuppliedResponse();
public Throwable getThrowable();
}
/**
* Listener for non-blocking read operations on ServletInputStream.
* Receives notifications when data is available to read.
*/
public interface ReadListener extends EventListener {
/** Invoked when data is available to read */
void onDataAvailable() throws IOException;
/** Invoked when all data has been read */
void onAllDataRead() throws IOException;
/** Invoked when an error occurs during reading */
void onError(Throwable t);
}
/**
* Listener for non-blocking write operations on ServletOutputStream.
* Receives notifications when it is possible to write data.
*/
public interface WriteListener extends EventListener {
/** Invoked when it is possible to write data without blocking */
void onWritePossible() throws IOException;
/** Invoked when an error occurs during writing */
void onError(Throwable t);
}
/**
* Provides connection metadata for servlet requests (introduced in Servlet 6.0).
*/
public interface ServletConnection {
/** Returns a connection identifier that is unique within the scope of the JVM */
String getConnectionId();
/** Returns the protocol used by the connection (e.g., "http/1.1", "h2") */
String getProtocol();
/** Returns an identifier for the protocol if the protocol provides one */
String getProtocolConnectionId();
/** Returns true if the connection is secure (HTTPS) */
boolean isSecure();
}
/**
* ServletInputStream with non-blocking I/O support.
*/
public abstract class ServletInputStream extends InputStream {
/** Reads input data into byte array */
public int readLine(byte[] b, int off, int len) throws IOException;
/** Returns true if all data has been read */
public abstract boolean isFinished();
/** Returns true if data can be read without blocking */
public abstract boolean isReady();
/** Sets the ReadListener for non-blocking I/O */
public abstract void setReadListener(ReadListener readListener);
}
/**
* ServletOutputStream with non-blocking I/O support.
*/
public abstract class ServletOutputStream extends OutputStream {
/** Writes a string to the output stream */
public void print(String s) throws IOException;
/** Writes a boolean to the output stream */
public void print(boolean b) throws IOException;
/** Writes a char to the output stream */
public void print(char c) throws IOException;
/** Writes an int to the output stream */
public void print(int i) throws IOException;
/** Writes a long to the output stream */
public void print(long l) throws IOException;
/** Writes a float to the output stream */
public void print(float f) throws IOException;
/** Writes a double to the output stream */
public void print(double d) throws IOException;
/** Writes a line separator */
public void println() throws IOException;
/** Writes a string followed by line separator */
public void println(String s) throws IOException;
/** Writes a boolean followed by line separator */
public void println(boolean b) throws IOException;
/** Writes a char followed by line separator */
public void println(char c) throws IOException;
/** Writes an int followed by line separator */
public void println(int i) throws IOException;
/** Writes a long followed by line separator */
public void println(long l) throws IOException;
/** Writes a float followed by line separator */
public void println(float f) throws IOException;
/** Writes a double followed by line separator */
public void println(double d) throws IOException;
/** Returns true if data can be written without blocking */
public abstract boolean isReady();
/** Sets the WriteListener for non-blocking I/O */
public abstract void setWriteListener(WriteListener writeListener);
}Configuration Note: To enable asynchronous processing, servlets must be configured with async support either via the @WebServlet(asyncSupported = true) annotation or programmatically using Wrapper.setAsyncSupported(true). Without this configuration, request.isAsyncSupported() returns false and async operations will fail.
Non-Blocking I/O Example:
@WebServlet(urlPatterns = "/async-read", asyncSupported = true)
public class NonBlockingReadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
ServletInputStream input = request.getInputStream();
input.setReadListener(new ReadListener() {
private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@Override
public void onDataAvailable() throws IOException {
byte[] bytes = new byte[1024];
int len;
while (input.isReady() && (len = input.read(bytes)) != -1) {
buffer.write(bytes, 0, len);
}
}
@Override
public void onAllDataRead() throws IOException {
byte[] data = buffer.toByteArray();
// Process the complete request data
response.getWriter().write("Received " + data.length + " bytes");
asyncContext.complete();
}
@Override
public void onError(Throwable t) {
asyncContext.complete();
}
});
}
}Support for processing multipart/form-data requests.
public interface Part {
InputStream getInputStream() throws IOException;
String getContentType();
String getName();
String getSubmittedFileName();
long getSize();
void write(String fileName) throws IOException;
void delete() throws IOException;
String getHeader(String name);
Collection<String> getHeaders(String name);
Collection<String> getHeaderNames();
}
public class MultipartConfigElement {
public MultipartConfigElement(String location);
public MultipartConfigElement(String location, long maxFileSize, long maxRequestSize,
int fileSizeThreshold);
public MultipartConfigElement(MultipartConfig annotation);
public String getLocation();
public long getMaxFileSize();
public long getMaxRequestSize();
public int getFileSizeThreshold();
}Configuration Note: To use the Part interface for multipart file uploads, servlets must be configured with multipart support either via the @MultipartConfig annotation or programmatically using Wrapper.setMultipartConfigElement(new MultipartConfigElement("/tmp")).
Forward and include functionality for internal request dispatching.
public interface RequestDispatcher {
static final String FORWARD_REQUEST_URI = "jakarta.servlet.forward.request_uri";
static final String FORWARD_CONTEXT_PATH = "jakarta.servlet.forward.context_path";
static final String FORWARD_PATH_INFO = "jakarta.servlet.forward.path_info";
static final String FORWARD_SERVLET_PATH = "jakarta.servlet.forward.servlet_path";
static final String FORWARD_QUERY_STRING = "jakarta.servlet.forward.query_string";
static final String FORWARD_MAPPING = "jakarta.servlet.forward.mapping";
static final String INCLUDE_REQUEST_URI = "jakarta.servlet.include.request_uri";
static final String INCLUDE_CONTEXT_PATH = "jakarta.servlet.include.context_path";
static final String INCLUDE_PATH_INFO = "jakarta.servlet.include.path_info";
static final String INCLUDE_SERVLET_PATH = "jakarta.servlet.include.servlet_path";
static final String INCLUDE_QUERY_STRING = "jakarta.servlet.include.query_string";
static final String INCLUDE_MAPPING = "jakarta.servlet.include.mapping";
static final String ERROR_EXCEPTION = "jakarta.servlet.error.exception";
static final String ERROR_EXCEPTION_TYPE = "jakarta.servlet.error.exception_type";
static final String ERROR_MESSAGE = "jakarta.servlet.error.message";
static final String ERROR_REQUEST_URI = "jakarta.servlet.error.request_uri";
static final String ERROR_SERVLET_NAME = "jakarta.servlet.error.servlet_name";
static final String ERROR_STATUS_CODE = "jakarta.servlet.error.status_code";
void forward(ServletRequest request, ServletResponse response)
throws ServletException, IOException;
void include(ServletRequest request, ServletResponse response)
throws ServletException, IOException;
}HTTP cookie management.
public class Cookie implements Cloneable {
public Cookie(String name, String value);
public void setComment(String purpose);
public String getComment();
public void setDomain(String pattern);
public String getDomain();
public void setMaxAge(int expiry);
public int getMaxAge();
public void setPath(String uri);
public String getPath();
public void setSecure(boolean flag);
public boolean getSecure();
public String getName();
public void setValue(String newValue);
public String getValue();
public int getVersion();
public void setVersion(int v);
public void setHttpOnly(boolean httpOnly);
public boolean isHttpOnly();
public void setAttribute(String name, String value);
public String getAttribute(String name);
public Map<String,String> getAttributes();
public Object clone();
}public class ServletException extends Exception {
public ServletException();
public ServletException(String message);
public ServletException(String message, Throwable rootCause);
public ServletException(Throwable rootCause);
public Throwable getRootCause();
}
public class UnavailableException extends ServletException {
public UnavailableException(String msg);
public UnavailableException(String msg, int seconds);
public boolean isPermanent();
public int getUnavailableSeconds();
}public enum DispatcherType {
FORWARD,
INCLUDE,
REQUEST,
ASYNC,
ERROR
}// Servlet declaration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {};
int loadOnStartup() default -1;
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
// Filter declaration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WebFilter {
String filterName() default "";
String[] value() default {};
String[] urlPatterns() default {};
DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};
WebInitParam[] initParams() default {};
String[] servletNames() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
// Listener declaration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WebListener {
String value() default "";
}
// Initialization parameter
@Target({})
@Retention(RetentionPolicy.RUNTIME)
public @interface WebInitParam {
String name();
String value();
String description() default "";
}
// Multipart configuration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MultipartConfig {
String location() default "";
long maxFileSize() default -1L;
long maxRequestSize() default -1L;
int fileSizeThreshold() default 0;
}
// Security constraints
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ServletSecurity {
HttpConstraint value() default @HttpConstraint;
HttpMethodConstraint[] httpMethodConstraints() default {};
}
@Target({})
@Retention(RetentionPolicy.RUNTIME)
public @interface HttpConstraint {
EmptyRoleSemantic value() default EmptyRoleSemantic.PERMIT;
String[] rolesAllowed() default {};
TransportGuarantee transportGuarantee() default TransportGuarantee.NONE;
}
@Target({})
@Retention(RetentionPolicy.RUNTIME)
public @interface HttpMethodConstraint {
String value();
EmptyRoleSemantic emptyRoleSemantic() default EmptyRoleSemantic.PERMIT;
String[] rolesAllowed() default {};
TransportGuarantee transportGuarantee() default TransportGuarantee.NONE;
}
public enum EmptyRoleSemantic {
PERMIT,
DENY
}
public enum TransportGuarantee {
NONE,
CONFIDENTIAL
}import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = "/hello", loadOnStartup = 1)
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html><body>");
out.println("<h1>Hello, " + req.getParameter("name") + "!</h1>");
out.println("</body></html>");
}
}import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
System.out.println("Request: " + httpRequest.getMethod() + " " + httpRequest.getRequestURI());
long start = System.currentTimeMillis();
chain.doFilter(request, response);
long duration = System.currentTimeMillis() - start;
System.out.println("Completed in " + duration + "ms");
}
}import jakarta.servlet.AsyncContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = "/async", asyncSupported = true)
public class AsyncServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
AsyncContext asyncContext = req.startAsync();
asyncContext.setTimeout(30000);
asyncContext.start(() -> {
try {
// Perform long-running operation
Thread.sleep(5000);
PrintWriter out = asyncContext.getResponse().getWriter();
out.println("Async operation completed");
asyncContext.complete();
} catch (Exception e) {
e.printStackTrace();
}
});
}
}import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/session-example")
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
Integer visitCount = (Integer) session.getAttribute("visitCount");
if (visitCount == null) {
visitCount = 1;
} else {
visitCount++;
}
session.setAttribute("visitCount", visitCount);
resp.setContentType("text/plain");
resp.getWriter().println("Visit count: " + visitCount);
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-tomcat-embed--tomcat-embed-core