Java Servlet API specification defining core interfaces and classes for web application development
—
The Java Servlet API provides comprehensive support for HTTP request and response processing. This includes handling different HTTP methods, processing request parameters and headers, managing response output, and supporting advanced features like multipart requests and HTTP/2 server push.
/**
* Abstract base class for HTTP servlets.
* Extends GenericServlet and provides HTTP-specific functionality.
*/
public abstract class HttpServlet extends GenericServlet {
/**
* Handle HTTP GET requests.
* Default implementation returns HTTP 405 (Method Not Allowed).
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
/**
* Handle HTTP POST requests.
* Default implementation returns HTTP 405 (Method Not Allowed).
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
/**
* Handle HTTP PUT requests.
* Default implementation returns HTTP 405 (Method Not Allowed).
*/
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_put_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
/**
* Handle HTTP DELETE requests.
* Default implementation returns HTTP 405 (Method Not Allowed).
*/
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_delete_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
/**
* Handle HTTP HEAD requests.
* Default implementation calls doGet and discards response body.
*/
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
NoBodyResponse response = new NoBodyResponse(resp);
doGet(req, response);
response.setContentLength();
}
/**
* Handle HTTP OPTIONS requests.
* Default implementation determines which methods are supported.
*/
protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Method[] methods = getAllDeclaredMethods(this.getClass());
boolean ALLOW_GET = false;
boolean ALLOW_HEAD = false;
boolean ALLOW_POST = false;
boolean ALLOW_PUT = false;
boolean ALLOW_DELETE = false;
boolean ALLOW_TRACE = true;
boolean ALLOW_OPTIONS = true;
// Check which doXXX methods are overridden
for (Method method : methods) {
if (method.getName().equals("doGet")) {
ALLOW_GET = true;
ALLOW_HEAD = true;
} else if (method.getName().equals("doPost")) {
ALLOW_POST = true;
} else if (method.getName().equals("doPut")) {
ALLOW_PUT = true;
} else if (method.getName().equals("doDelete")) {
ALLOW_DELETE = true;
}
}
StringBuilder allow = new StringBuilder();
if (ALLOW_GET) allow.append("GET");
if (ALLOW_HEAD) append(allow, "HEAD");
if (ALLOW_POST) append(allow, "POST");
if (ALLOW_PUT) append(allow, "PUT");
if (ALLOW_DELETE) append(allow, "DELETE");
if (ALLOW_TRACE) append(allow, "TRACE");
if (ALLOW_OPTIONS) append(allow, "OPTIONS");
resp.setHeader("Allow", allow.toString());
}
/**
* Handle HTTP TRACE requests.
* Default implementation reflects the request back as the response.
*/
protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String CRLF = "\r\n";
StringBuilder buffer = new StringBuilder("TRACE ")
.append(req.getRequestURI())
.append(" ")
.append(req.getProtocol())
.append(CRLF);
Enumeration<String> reqHeaderEnum = req.getHeaderNames();
while (reqHeaderEnum.hasMoreElements()) {
String headerName = reqHeaderEnum.nextElement();
buffer.append(headerName).append(": ")
.append(req.getHeader(headerName)).append(CRLF);
}
buffer.append(CRLF);
int responseLength = buffer.length();
resp.setContentType("message/http");
resp.setContentLength(responseLength);
ServletOutputStream out = resp.getOutputStream();
out.print(buffer.toString());
}
/**
* Get the last modified time for the resource.
* Default returns -1 (unknown).
*/
protected long getLastModified(HttpServletRequest req) {
return -1;
}
/**
* Dispatch HTTP requests to appropriate doXXX methods.
*/
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException("Non-HTTP request or response");
}
service(request, response);
}
/**
* HTTP-specific service method that dispatches to doXXX methods.
*/
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req, resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
}/**
* HTTP-specific servlet request interface.
* Extends ServletRequest with HTTP-specific functionality.
*/
public interface HttpServletRequest extends ServletRequest {
// HTTP method constants
public static final String BASIC_AUTH = "BASIC";
public static final String FORM_AUTH = "FORM";
public static final String CLIENT_CERT_AUTH = "CLIENT_CERT";
public static final String DIGEST_AUTH = "DIGEST";
// Request attributes for authentication
public static final String AUTHORIZATION = "javax.servlet.http.authorization";
public static final String REMOTE_USER = "javax.servlet.http.remoteUser";
/**
* Get the authentication scheme (BASIC, FORM, etc.)
*/
String getAuthType();
/**
* Get all cookies sent with this request.
*/
Cookie[] getCookies();
/**
* Get the value of a date header.
*/
long getDateHeader(String name);
/**
* Get the value of a request header.
*/
String getHeader(String name);
/**
* Get all values for a header with multiple values.
*/
Enumeration<String> getHeaders(String name);
/**
* Get all header names in this request.
*/
Enumeration<String> getHeaderNames();
/**
* Get the value of an integer header.
*/
int getIntHeader(String name);
/**
* Get servlet mapping information for this request.
*/
HttpServletMapping getHttpServletMapping();
/**
* Get the HTTP method (GET, POST, etc.)
*/
String getMethod();
/**
* Get extra path information after servlet path.
*/
String getPathInfo();
/**
* Get real path corresponding to path info.
*/
String getPathTranslated();
/**
* Get the context path portion of the request URL.
*/
String getContextPath();
/**
* Get the query string from the request URL.
*/
String getQueryString();
/**
* Get the login name of the authenticated user.
*/
String getRemoteUser();
/**
* Check if the user is in the specified role.
*/
boolean isUserInRole(String role);
/**
* Get the Principal object for the authenticated user.
*/
java.security.Principal getUserPrincipal();
/**
* Get the session ID from the request.
*/
String getRequestedSessionId();
/**
* Get the full request URI.
*/
String getRequestURI();
/**
* Get the full request URL including query string.
*/
StringBuffer getRequestURL();
/**
* Get the servlet path portion of the request URL.
*/
String getServletPath();
/**
* Get the current session, creating one if necessary.
*/
HttpSession getSession(boolean create);
/**
* Get the current session (create = true).
*/
HttpSession getSession();
/**
* Change the session ID and return the new ID.
*/
String changeSessionId();
/**
* Check if the session ID came from a cookie.
*/
boolean isRequestedSessionIdValid();
/**
* Check if the session ID is still valid.
*/
boolean isRequestedSessionIdFromCookie();
/**
* Check if the session ID came from URL encoding.
*/
boolean isRequestedSessionIdFromURL();
/**
* Check if the session ID came from URL encoding (deprecated).
*/
@Deprecated
boolean isRequestedSessionIdFromUrl();
/**
* Programmatically authenticate the user.
*/
boolean authenticate(HttpServletResponse response)
throws IOException, ServletException;
/**
* Programmatically log in the user.
*/
void login(String username, String password) throws ServletException;
/**
* Programmatically log out the user.
*/
void logout() throws ServletException;
/**
* Get all parts from a multipart/form-data request.
*/
Collection<Part> getParts() throws IOException, ServletException;
/**
* Get a specific part by name from a multipart request.
*/
Part getPart(String name) throws IOException, ServletException;
/**
* Create an HttpUpgradeHandler for protocol upgrade.
*/
<T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass)
throws IOException, ServletException;
}/**
* HTTP-specific servlet response interface.
* Extends ServletResponse with HTTP-specific functionality.
*/
public interface HttpServletResponse extends ServletResponse {
// Status code constants
public static final int SC_CONTINUE = 100;
public static final int SC_SWITCHING_PROTOCOLS = 101;
public static final int SC_OK = 200;
public static final int SC_CREATED = 201;
public static final int SC_ACCEPTED = 202;
public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
public static final int SC_NO_CONTENT = 204;
public static final int SC_RESET_CONTENT = 205;
public static final int SC_PARTIAL_CONTENT = 206;
public static final int SC_MULTIPLE_CHOICES = 300;
public static final int SC_MOVED_PERMANENTLY = 301;
public static final int SC_MOVED_TEMPORARILY = 302;
public static final int SC_FOUND = 302;
public static final int SC_SEE_OTHER = 303;
public static final int SC_NOT_MODIFIED = 304;
public static final int SC_USE_PROXY = 305;
public static final int SC_TEMPORARY_REDIRECT = 307;
public static final int SC_BAD_REQUEST = 400;
public static final int SC_UNAUTHORIZED = 401;
public static final int SC_PAYMENT_REQUIRED = 402;
public static final int SC_FORBIDDEN = 403;
public static final int SC_NOT_FOUND = 404;
public static final int SC_METHOD_NOT_ALLOWED = 405;
public static final int SC_NOT_ACCEPTABLE = 406;
public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
public static final int SC_REQUEST_TIMEOUT = 408;
public static final int SC_CONFLICT = 409;
public static final int SC_GONE = 410;
public static final int SC_LENGTH_REQUIRED = 411;
public static final int SC_PRECONDITION_FAILED = 412;
public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
public static final int SC_REQUEST_URI_TOO_LONG = 414;
public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
public static final int SC_EXPECTATION_FAILED = 417;
public static final int SC_INTERNAL_SERVER_ERROR = 500;
public static final int SC_NOT_IMPLEMENTED = 501;
public static final int SC_BAD_GATEWAY = 502;
public static final int SC_SERVICE_UNAVAILABLE = 503;
public static final int SC_GATEWAY_TIMEOUT = 504;
public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
/**
* Add a cookie to the response.
*/
void addCookie(Cookie cookie);
/**
* Check if the response contains the specified header.
*/
boolean containsHeader(String name);
/**
* Encode a URL for session tracking via URL rewriting.
*/
String encodeURL(String url);
/**
* Encode a redirect URL for session tracking.
*/
String encodeRedirectURL(String url);
/**
* Encode a URL for session tracking (deprecated).
*/
@Deprecated
String encodeUrl(String url);
/**
* Encode a redirect URL for session tracking (deprecated).
*/
@Deprecated
String encodeRedirectUrl(String url);
/**
* Send an error response with the specified status code.
*/
void sendError(int sc, String msg) throws IOException;
/**
* Send an error response with the specified status code.
*/
void sendError(int sc) throws IOException;
/**
* Send a redirect response to the specified URL.
*/
void sendRedirect(String location) throws IOException;
/**
* Set a date header with the given value.
*/
void setDateHeader(String name, long date);
/**
* Add a date header with the given value.
*/
void addDateHeader(String name, long date);
/**
* Set a header with the given value.
*/
void setHeader(String name, String value);
/**
* Add a header with the given value.
*/
void addHeader(String name, String value);
/**
* Set an integer header with the given value.
*/
void setIntHeader(String name, int value);
/**
* Add an integer header with the given value.
*/
void addIntHeader(String name, int value);
/**
* Set the response status code.
*/
void setStatus(int sc);
/**
* Set the response status code with message (deprecated).
*/
@Deprecated
void setStatus(int sc, String sm);
/**
* Get the response status code.
*/
int getStatus();
/**
* Get the value of a response header.
*/
String getHeader(String name);
/**
* Get all values for a response header.
*/
Collection<String> getHeaders(String name);
/**
* Get all response header names.
*/
Collection<String> getHeaderNames();
/**
* Get trailer fields for chunked encoding.
*/
Supplier<Map<String, String>> getTrailerFields();
/**
* Set trailer fields for chunked encoding.
*/
void setTrailerFields(Supplier<Map<String, String>> supplier);
}/**
* Interface representing a part in a multipart/form-data request.
*/
public interface Part {
/**
* Get an InputStream for reading the part content.
*/
InputStream getInputStream() throws IOException;
/**
* Get the content type of this part.
*/
String getContentType();
/**
* Get the name of this part (from the name attribute).
*/
String getName();
/**
* Get the submitted filename (from filename attribute).
*/
String getSubmittedFileName();
/**
* Get the size of this part in bytes.
*/
long getSize();
/**
* Write this part to a file on disk.
*/
void write(String fileName) throws IOException;
/**
* Delete any temporary storage for this part.
*/
void delete() throws IOException;
/**
* Get the value of a header for this part.
*/
String getHeader(String name);
/**
* Get all values for a header.
*/
Collection<String> getHeaders(String name);
/**
* Get all header names for this part.
*/
Collection<String> getHeaderNames();
}/**
* Servlet configured for multipart request handling
*/
@WebServlet("/upload")
@MultipartConfig(
location = "/tmp",
fileSizeThreshold = 1024 * 1024, // 1 MB
maxFileSize = 1024 * 1024 * 5, // 5 MB
maxRequestSize = 1024 * 1024 * 5 * 5 // 25 MB
)
public class FileUploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Process regular form parameters
String description = request.getParameter("description");
// Process uploaded files
for (Part part : request.getParts()) {
if (part.getName().equals("file") && part.getSize() > 0) {
String fileName = getSubmittedFileName(part);
// Validate file type
String contentType = part.getContentType();
if (!isValidContentType(contentType)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Invalid file type: " + contentType);
return;
}
// Save the file
String uploadPath = getServletContext().getRealPath("/uploads");
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
String filePath = uploadPath + File.separator + fileName;
part.write(filePath);
// Log the upload
log("File uploaded: " + fileName + " (" + part.getSize() + " bytes)");
}
}
response.setContentType("application/json");
response.getWriter().write("{\"status\":\"success\",\"message\":\"Files uploaded\"}");
}
private String getSubmittedFileName(Part part) {
String contentDisposition = part.getHeader("Content-Disposition");
String[] elements = contentDisposition.split(";");
for (String element : elements) {
if (element.trim().startsWith("filename")) {
return element.substring(element.indexOf('=') + 1)
.trim().replace("\"", "");
}
}
return "unknown";
}
private boolean isValidContentType(String contentType) {
return contentType != null && (
contentType.startsWith("image/") ||
contentType.equals("application/pdf") ||
contentType.startsWith("text/")
);
}
}/**
* Interface for HTTP/2 server push functionality.
*/
public interface PushBuilder {
/**
* Set the HTTP method for the push request.
*/
PushBuilder method(String method);
/**
* Set the query string for the push request.
*/
PushBuilder queryString(String queryString);
/**
* Set the session ID for the push request.
*/
PushBuilder sessionId(String sessionId);
/**
* Set a header for the push request.
*/
PushBuilder setHeader(String name, String value);
/**
* Add a header to the push request.
*/
PushBuilder addHeader(String name, String value);
/**
* Remove a header from the push request.
*/
PushBuilder removeHeader(String name);
/**
* Set the path for the push request.
*/
PushBuilder path(String path);
/**
* Initiate the server push.
*/
void push();
/**
* Get the HTTP method for the push request.
*/
String getMethod();
/**
* Get the query string for the push request.
*/
String getQueryString();
/**
* Get the session ID for the push request.
*/
String getSessionId();
/**
* Get all header names for the push request.
*/
Set<String> getHeaderNames();
/**
* Get the value of a header for the push request.
*/
String getHeader(String name);
/**
* Get the path for the push request.
*/
String getPath();
}/**
* Servlet demonstrating HTTP/2 server push
*/
public class ServerPushServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Check if server push is supported
PushBuilder pushBuilder = request.newPushBuilder();
if (pushBuilder != null) {
// Push CSS resources
pushBuilder.path("/css/styles.css")
.setHeader("Content-Type", "text/css")
.push();
// Push JavaScript resources
pushBuilder.path("/js/app.js")
.setHeader("Content-Type", "application/javascript")
.push();
// Push image resources
pushBuilder.path("/images/logo.png")
.setHeader("Content-Type", "image/png")
.push();
}
// Generate the main HTML response
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println(" <title>Server Push Example</title>");
out.println(" <link rel=\"stylesheet\" href=\"/css/styles.css\">");
out.println("</head>");
out.println("<body>");
out.println(" <img src=\"/images/logo.png\" alt=\"Logo\">");
out.println(" <h1>Welcome to Server Push Demo</h1>");
out.println(" <script src=\"/js/app.js\"></script>");
out.println("</body>");
out.println("</html>");
}
}/**
* HTTP servlet request wrapper for request modification/decoration.
*/
public class HttpServletRequestWrapper extends ServletRequestWrapper
implements HttpServletRequest {
private HttpServletRequest request;
public HttpServletRequestWrapper(HttpServletRequest request) {
super(request);
if (request == null) {
throw new IllegalArgumentException("Request cannot be null");
}
this.request = request;
}
// Delegate all methods to wrapped request
public String getAuthType() {
return this.request.getAuthType();
}
public Cookie[] getCookies() {
return this.request.getCookies();
}
public long getDateHeader(String name) {
return this.request.getDateHeader(name);
}
public String getHeader(String name) {
return this.request.getHeader(name);
}
// ... all other HttpServletRequest methods
}
/**
* HTTP servlet response wrapper for response modification/decoration.
*/
public class HttpServletResponseWrapper extends ServletResponseWrapper
implements HttpServletResponse {
private HttpServletResponse response;
public HttpServletResponseWrapper(HttpServletResponse response) {
super(response);
if (response == null) {
throw new IllegalArgumentException("Response cannot be null");
}
this.response = response;
}
// Delegate all methods to wrapped response
public void addCookie(Cookie cookie) {
this.response.addCookie(cookie);
}
public boolean containsHeader(String name) {
return this.response.containsHeader(name);
}
public String encodeURL(String url) {
return this.response.encodeURL(url);
}
// ... all other HttpServletResponse methods
}/**
* REST API servlet for JSON processing
*/
@WebServlet("/api/users/*")
public class UserAPIServlet extends HttpServlet {
private final ObjectMapper mapper = new ObjectMapper();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String pathInfo = request.getPathInfo();
response.setContentType("application/json;charset=UTF-8");
try {
if (pathInfo == null || pathInfo.equals("/")) {
// Get all users
List<User> users = getUserService().getAllUsers();
writeJsonResponse(response, users);
} else {
// Get specific user
String userId = pathInfo.substring(1);
User user = getUserService().getUser(userId);
if (user != null) {
writeJsonResponse(response, user);
} else {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
writeJsonResponse(response, Map.of("error", "User not found"));
}
}
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
writeJsonResponse(response, Map.of("error", "Internal server error"));
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json;charset=UTF-8");
try {
// Read JSON request body
User user = mapper.readValue(request.getInputStream(), User.class);
// Validate user data
if (user.getName() == null || user.getEmail() == null) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
writeJsonResponse(response, Map.of("error", "Name and email are required"));
return;
}
// Create user
User createdUser = getUserService().createUser(user);
response.setStatus(HttpServletResponse.SC_CREATED);
writeJsonResponse(response, createdUser);
} catch (JsonProcessingException e) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
writeJsonResponse(response, Map.of("error", "Invalid JSON"));
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
writeJsonResponse(response, Map.of("error", "Internal server error"));
}
}
@Override
protected void doPut(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String pathInfo = request.getPathInfo();
if (pathInfo == null || pathInfo.equals("/")) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
response.setContentType("application/json;charset=UTF-8");
try {
String userId = pathInfo.substring(1);
User user = mapper.readValue(request.getInputStream(), User.class);
user.setId(userId);
User updatedUser = getUserService().updateUser(user);
if (updatedUser != null) {
writeJsonResponse(response, updatedUser);
} else {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
writeJsonResponse(response, Map.of("error", "User not found"));
}
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
writeJsonResponse(response, Map.of("error", "Internal server error"));
}
}
@Override
protected void doDelete(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String pathInfo = request.getPathInfo();
if (pathInfo == null || pathInfo.equals("/")) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
response.setContentType("application/json;charset=UTF-8");
try {
String userId = pathInfo.substring(1);
boolean deleted = getUserService().deleteUser(userId);
if (deleted) {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
} else {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
writeJsonResponse(response, Map.of("error", "User not found"));
}
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
writeJsonResponse(response, Map.of("error", "Internal server error"));
}
}
private void writeJsonResponse(HttpServletResponse response, Object data)
throws IOException {
PrintWriter writer = response.getWriter();
mapper.writeValue(writer, data);
writer.flush();
}
}This comprehensive coverage of HTTP request and response processing provides all the tools needed for handling HTTP communications in servlet applications, from basic request processing to advanced features like multipart uploads and HTTP/2 server push.
Install with Tessl CLI
npx tessl i tessl/maven-javax-servlet--javax-servlet-api