CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-javax-servlet--javax-servlet-api

Java Servlet API specification defining core interfaces and classes for web application development

Pending
Overview
Eval results
Files

http-processing.mddocs/

HTTP Request and Response Processing

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.

HttpServlet Base Class

/**
 * 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);
        }
    }
}

HttpServletRequest Interface

/**
 * 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;
}

HttpServletResponse Interface

/**
 * 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);
}

Multipart Request Processing

Part Interface

/**
 * 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();
}

Multipart Configuration Examples

/**
 * 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/")
        );
    }
}

HTTP/2 Server Push Support

PushBuilder Interface

/**
 * 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();
}

Server Push Example

/**
 * 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>");
    }
}

Request and Response Wrapper Classes

/**
 * 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
}

Content Processing Examples

JSON API Servlet

/**
 * 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

docs

async-processing.md

http-processing.md

index.md

listeners-events.md

security-filtering.md

servlet-lifecycle.md

session-cookies.md

tile.json