Request and response
A servlet method receives two objects. HttpServletRequest is everything the client sent: the address, parameters, headers, form data. HttpServletResponse is what goes back: the status code, headers and body. Let's build a search and a subscription form for the blog.
Request parameters
A parameter from the query string (?q=java) is read with getParameter. Create the file src/main/java/com/example/blog/SearchServlet.java:
// src/main/java/com/example/blog/SearchServlet.java
package com.example.blog;
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("/search")
public class SearchServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/plain; charset=UTF-8");
PrintWriter out = response.getWriter();
String query = request.getParameter("q");
if (query == null || query.isBlank()) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
out.println("Parameter q is required");
return;
}
response.setHeader("X-Search-Query", query);
out.println("Searching posts for: " + query);
}
}When the parameter is missing, getParameter returns null. Then the servlet sets status 400 and reports the error. Otherwise it adds its own header and prints the query.
curl -i "http://localhost:8080/blog/search?q=java"HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
X-Search-Query: java
Content-Length: 27
Searching posts for: java
Without the parameter (curl -i http://localhost:8080/blog/search) you get HTTP/1.1 400 Bad Request and the text Parameter q is required.
Form data and redirect
Fields of an HTML form sent with POST are read with the same getParameter. After handling a form it is customary to redirect the browser to another page:
// src/main/java/com/example/blog/SubscribeServlet.java
package com.example.blog;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/subscribe")
public class SubscribeServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String email = request.getParameter("email");
System.out.println("New subscriber: " + email);
response.sendRedirect(request.getContextPath() + "/hello");
}
}getContextPath() returns /blog, so the redirect address does not depend on server settings. Let's submit the form with curl:
curl -i -d "email=anna@example.com" http://localhost:8080/blog/subscribeHTTP/1.1 302 Found
Location: http://localhost:8080/blog/hello
The server log gets the line New subscriber: anna@example.com.
Useful methods
| Method | What it returns or does |
|---|---|
request.getParameter("q") | Parameter value or null |
request.getHeader("User-Agent") | Header value |
request.getMethod() | GET, POST and so on |
request.getRequestURI() | The path, for example /blog/search |
response.setStatus(404) | Status code |
response.setHeader(name, value) | Response header |
response.sendRedirect(url) | A 302 response with an address |
response.sendError(404) | The server's standard error page |
Common mistake
Calling setContentType after getWriter(). The encoding is chosen when you get the PrintWriter, and a late call changes nothing: the server sends Content-Type: text/plain; charset=ISO-8859-1, letters outside Latin-1 turn into ????, and café reaches a UTF-8 client as caf�. Set the type and encoding first, then call getWriter(). For the same reason, keep messages passed to sendError in plain ASCII — the server error page is also written in ISO-8859-1.