Tutorials Logic, IN info@tutorialslogic.com

Servlet Request Response Objects

Request Response Boundary

Every servlet invocation receives one HttpServletRequest and one HttpServletResponse from the container. The request describes what the client sent; the response is the message your servlet is building for the client. Keeping that boundary clear prevents accidental sessions, incorrect encodings, and responses that are committed before their status or headers are ready.

After this lesson, you can distinguish parameters, attributes, headers, and body data; choose a character writer or binary stream; return a deliberate status and content type; and recognize when forwarding, redirecting, or writing a body changes the request lifecycle.

Request Data Sources

HttpServletRequest extends ServletRequest with HTTP-specific information. Query strings and form fields are exposed as parameters. Headers describe metadata such as accepted media types and authentication. Attributes are server-side values attached by a filter or servlet and exist only for the current request. The body is a byte or character stream and should be read once by the component that owns it.

Use getParameter() for query parameters and URL-encoded form fields, getHeader() for protocol metadata, and getAttribute() for values created inside the application. Treat every client-controlled value as untrusted: check null, length, expected format, and authorization before using it in a database query, file path, or rendered HTML.

Source Servlet API Typical use
Query or form field getParameter / getParameterValues Search filters, form values
HTTP header getHeader Accept, Authorization, User-Agent
Server attribute getAttribute / setAttribute Filter-to-controller or forward data
Text body getReader JSON or other character data
Binary body getInputStream Uploads or binary protocols

HttpServletRequest Methods

HttpServletRequest Methods
@WebServlet("/request-demo")
public class RequestDemoServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        // ===== Request Parameters =====
        String name   = req.getParameter("name");           // Single value
        String[] tags = req.getParameterValues("tags");     // Multiple values (checkboxes)
        java.util.Map<String, String[]> params = req.getParameterMap(); // All params

        // ===== Request Headers =====
        String userAgent    = req.getHeader("User-Agent");
        String contentType  = req.getContentType();
        String accept       = req.getHeader("Accept");
        java.util.Enumeration<String> headerNames = req.getHeaderNames();

        // ===== Request Info =====
        String method      = req.getMethod();          // GET, POST, etc.
        String uri         = req.getRequestURI();      // /myapp/request-demo
        String url         = req.getRequestURL().toString(); // http://localhost:8080/myapp/request-demo
        String contextPath = req.getContextPath();     // /myapp
        String servletPath = req.getServletPath();     // /request-demo
        String queryString = req.getQueryString();     // name=Alice&age=25
        String remoteAddr  = req.getRemoteAddr();      // Client IP
        String remoteHost  = req.getRemoteHost();      // Client hostname
        int    serverPort  = req.getServerPort();      // 8080

        // ===== Request Attributes (set by other servlets/filters) =====
        req.setAttribute("processedBy", "RequestDemoServlet");
        Object attr = req.getAttribute("processedBy");

        // ===== Session =====
        HttpSession session = req.getSession();        // Get or create session
        HttpSession existing = req.getSession(false);  // Get only if exists

        // ===== Cookies =====
        Cookie[] cookies = req.getCookies();

        // ===== Request Body (for POST) =====
        // req.getInputStream() - binary data
        // req.getReader()      - text data

        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<p>Method: " + method + "</p>");
        out.println("<p>URI: " + uri + "</p>");
        out.println("<p>Name param: " + name + "</p>");
        out.println("<p>Remote IP: " + remoteAddr + "</p>");
    }
}

Response Construction

HttpServletResponse controls status, headers, cookies, content type, character encoding, and body output. Set status, content type, and encoding before calling getWriter() or getOutputStream(). Once the response buffer is flushed or filled, the response is committed and the container may already have sent its headers.

Choose getWriter() for character output such as HTML, JSON, or text, and getOutputStream() for bytes such as an image or generated archive. Do not use both for one response. A successful handler should select the status that describes the result instead of returning 200 for every outcome: 201 for a created resource, 204 for success without a body, 400 for invalid syntax, 404 for a missing resource, and 500 only for an unexpected server failure.

HttpServletResponse Methods

HttpServletResponse Methods
@WebServlet("/response-demo")
public class ResponseDemoServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        String format = req.getParameter("format");

        if ("json".equals(format)) {
            // ===== JSON Response =====
            resp.setContentType("application/json;charset=UTF-8");
            resp.setStatus(HttpServletResponse.SC_OK);
            PrintWriter out = resp.getWriter();
            out.println("{\"name\":\"Alice\",\"age\":25,\"role\":\"admin\"}");

        } else if ("file".equals(format)) {
            // ===== File Download =====
            resp.setContentType("application/octet-stream");
            resp.setHeader("Content-Disposition", "attachment; filename=\"data.txt\"");
            resp.getWriter().println("File content here");

        } else {
            // ===== HTML Response =====
            resp.setContentType("text/html;charset=UTF-8");
            resp.setCharacterEncoding("UTF-8");

            // Set response headers
            resp.setHeader("X-Custom-Header", "MyValue");
            resp.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            resp.setIntHeader("X-Request-Count", 42);
            resp.setDateHeader("Expires", 0);

            // Set status code
            resp.setStatus(HttpServletResponse.SC_OK); // 200

            PrintWriter out = resp.getWriter();
            out.println("<h2>Response Demo</h2>");
            out.println("<p>Content-Type: " + resp.getContentType() + "</p>");
            out.println("<p>Buffer size: " + resp.getBufferSize() + "</p>");
        }
    }
}

JSON Body Handling

A JSON request body is not a request parameter. Read it through getReader(), enforce a body-size limit at the container or application boundary, parse it with a maintained JSON library, and validate the resulting object. Hand-written substring parsing breaks on escaped characters, missing fields, and reordered properties.

Fetch resolves even when the server returns an HTTP error status, so a JSON endpoint should send both a meaningful status and a consistent error representation. Never echo raw exception messages, SQL details, access tokens, or stack traces to the client.

Reading JSON POST Body

Reading JSON POST Body
@WebServlet("/api/users")
public class UserApiServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        // Read JSON body from request
        StringBuilder sb = new StringBuilder();
        java.io.BufferedReader reader = req.getReader();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        String jsonBody = sb.toString();
        // jsonBody = {"name":"Alice","email":"alice@example.com"}

        // Parse JSON (using a library like Gson or Jackson in real apps)
        // For demo: simple string parsing
        System.out.println("Received JSON: " + jsonBody);

        // Send JSON response
        resp.setContentType("application/json;charset=UTF-8");
        resp.setStatus(HttpServletResponse.SC_CREATED); // 201
        resp.getWriter().println("{\"status\":\"created\",\"message\":\"User created successfully\"}");
    }
}

Forward Redirect Write

A RequestDispatcher forward stays inside the same application and keeps request attributes because the target continues the same request. sendRedirect() sends a redirect response to the client, which then creates a new request and sees a new URL. Direct body writing ends the handler with content produced by the current servlet.

Choose a forward when another server-side resource should finish rendering the current request. Choose a redirect after a successful state-changing form submission when a fresh GET prevents duplicate submission. Never write response content before a forward or redirect unless the API explicitly expects an included resource.

  • Use request attributes for values needed by a forwarded JSP or servlet.
  • Build redirect paths with getContextPath() so deployment under a non-root context still works.
  • Return immediately after sendError(), sendRedirect(), or a completed forward.
  • Avoid storing request or response objects in servlet fields because containers handle requests concurrently.
Before you move on

Request Response Review

5 checks
  • Identify whether each input comes from a parameter, header, attribute, or body.
  • Validate client-controlled values before they reach business or persistence code.
  • Set status, content type, and encoding before obtaining the response writer.
  • Use one output mechanism and stop processing after terminal response actions.
  • Keep request and response objects inside the current request thread.

Boundary Failures

  • Reading JSON with getParameter()

    Read the body with getReader() and parse it with a JSON library.
  • Setting headers after writing

    Prepare status and headers before body output can commit the response.
  • Printing unescaped form data

    Validate input and use context-aware output escaping in the final HTML view.

Try this next

Trace One Exchange

0 of 3 completed

  1. Create a GET endpoint that returns its method, URI, one query parameter, and Accept header as JSON.
  2. Add a POST endpoint that returns 400 with a stable JSON error object when a required field is absent.
  3. Implement one forward and one redirect, then record which URL and request attributes the target receives.

Request Response Decisions

No. They are two views of the same request body; choose the character or binary API that matches the media type.

It returns an existing session or null without creating one, which avoids creating sessions for anonymous requests that do not need state.

It is committed after the container sends headers, commonly when the buffer fills, is flushed, or the request completes.

Next Step
Next Practice

Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.