Servlet and JSP interview questions: servlet lifecycle, request/response, sessions, filters and JSP tags.
29 questions
Three phases:
The container manages the lifecycle; the developer only overrides the methods needed.
For each request the container picks a (possibly new) thread and calls service() on the same servlet instance. The servlet is instantiated once and shared, so instance fields are shared across threads - meaning servlets are not thread-safe unless you synchronise or keep no mutable state.
Best practice: store per-request data in request/session attributes and keep servlets stateless. Local variables are fine because each thread has its own stack.
forward() (RequestDispatcher) happens server-side: the request is passed to another resource, the URL does not change and it costs one round trip.
sendRedirect() is client-side: the server returns a 3xx status and the browser issues a second request to the new URL, the URL changes, and the request/session data must be carried explicitly.
The container creates an HttpSession and hands it to the browser as a cookie (usually JSESSIONID). On following requests the cookie identifies the session, and request.getSession() returns the same object.
If cookies are disabled, the container can rewrite URLs with encodeURL() to keep the session id in the URL. Sessions hold user state across requests and can be invalidated, given timeouts, or stored in memory or a store.
A Filter intercepts requests before they reach a servlet and/or responses after. Filter chains are declared with @WebFilter or web.xml and can short-circuit the chain (e.g. reject a request).
Typical uses: authentication/authorisation, request logging, compression, encoding (UTF-8), CORS headers, XSS defence and rate limiting.
JSP is a view technology mixing HTML with Java tags and scriptlets. EL (Expression Language) is the simplified syntax ${user.name} to read beans in JSP pages. JSTL is the standard tag library (<c:forEach>, <c:if>) that replaces scriptlets with clean tags.
Modern practice favours templates over JSP, but the underlying request/response model remains the same.
A servlet is a Java class that runs inside a servlet container (Tomcat, Jetty) and processes HTTP requests. It maps a request (URL + method) to Java code that can query a DB, compute a result and write a response. Servlets form the controller layer in classic Java web applications.
init and destroy run exactly once; service runs many times, typically on a pooled thread per request.
A servlet is a singleton: the container creates one instance and dispatches all requests to it, each on its own worker thread. You therefore must not use mutable instance fields for per-request data. Keep per-request state in local variables, request scope or session scope; synchronize only if you genuinely share mutable state across threads.
ServletConfig holds init parameters and a reference to the context for one servlet - it is per-servlet. ServletContext is application-wide and shared by all servlets: it exposes application init parameters, the real path of resources, and lets components store application-scoped attributes.
request.getSession(true) creates or returns the session. The container generates a session id, keeps it in a cookie (JSESSIONID) or via URL rewriting, and stores the HttpSession server-side (memory, or a distributed store when clustered). Attributes set with setAttribute survive across requests from the same client until the session is invalidated or times out.
JSESSIONID cannot be stored in a cookie, so the container falls back to URL rewriting: it appends a session id parameter to every URL. For this to work, links must be encoded with response.encodeURL(url) (some JSPs do it automatically) and redirections with encodeRedirectURL; otherwise the session cannot be tracked.
Filters run before the servlet (and after, on the way out) and can preprocess requests and postprocess responses - logging, authentication, compression, character encoding, CORS, header injection. Filters are chained; each calls chain.doFilter() to pass the request onward. Configure with @WebFilter or web.xml.
A servlet owns an endpoint and produces the response. A filter is an interceptor: it wraps the request/response, may short-circuit the chain (for example deny access), and never has its own endpoint. Filters run before the servlet for all matching requests and can also filter responses.
Listeners observe lifecycle events. ServletContextListener fires on context startup and shutdown (a common place to init pools or schedulers); HttpSessionListener tracks session creation/destruction; ServletRequestListener tracks request begin/end. They let you hook initialization and cleanup logic declaratively.
GET sends parameters in the URL query string - visible, cached, limited in length, and appropriate for idempotent reads. POST sends parameters in the request body - invisible in the URL, no practical size limit, and used for state-changing operations. The servlet service() dispatches to doGet()/doPost() respectively.
Use request.getParameter("name") for a single value, request.getParameterValues("hobby") for multiple values of the same name (checkboxes), and request.getParameterMap() to get everything. Values arrive as Strings, so numeric fields must be parsed manually.
An HTML form with enctype="multipart/form-data" sends each file as a part of the request body. The servlet must be annotated @MultipartConfig. Then read the part and save it:
@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
Part file = req.getPart("file");
file.write("/uploads/" + file.getSubmittedFileName());
}
}Encoding decides how bytes are translated to characters. If the browser and the server disagree, non-ASCII text (names, other languages, emoji) becomes garbled. Set request.setCharacterEncoding("UTF-8") before reading parameters and response.setCharacterEncoding("UTF-8") (or setCharacterContentType) before writing output; also configure the container URI encoding for the URL itself.
JSP (JavaServer Pages) is a template technology for building views. At deployment the container translates a .jsp into a servlet class - it literally becomes a servlet. JSP focuses on markup with tags and expressions for presentation, while servlets focus on request handling and logic.
<%! ... %> - define methods and fields that become members of the generated servlet class.<% ... %> - arbitrary Java code inserted into the _jspService() method.<%= expr %> - evaluate an expression and print it to the output.Best practice: avoid scriptlets entirely; use JSTL with EL instead.
Implicit objects are variables available automatically inside every JSP. The main ones: request, response, session, application (ServletContext), out (JspWriter), config, pageContext, page and exception. They simplify access to request/session data and output writing.
EL reads data concisely and safely inside templates: ${user.name}, ${sessionScope.cart.size()}. Unlike scriptlets, EL separates presentation from logic, cannot access arbitrary Java, and fails gracefully with null. With the JSTL tag library, most dynamic pages need no scriptlet code at all.
JSTL (JSP Standard Tag Library) is a set of tag libraries replacing scriptlets. Common core tags (c: prefix): <c:if>, <c:choose>/<c:when>/<c:otherwise>, <c:forEach>, <c:out> and <c:set>. Others: fmt for formatting, fn for string functions, sql for DB access (discouraged in MVC).
The include directive <%@ include file="x.jsp" %> is a compile-time include - the content is inlined once at translation time, so it runs quickly but changes require recompilation. The <jsp:include> tag includes the resource at request time; the included page is executed separately, so it is more flexible but slightly slower.
Four mechanisms: cookies (default, JSESSIONID), URL rewriting (jsessionid appended to URLs when cookies fail), hidden form fields (state travels with each form submit), and secure HTTPS session ids or a backing store/key shared with the container. Cookies and URL rewriting are used by the servlet API; hidden fields are manual state tracking.
Define the page in web.xml by error code or exception type:
<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.jsp</location>
</error-page>Or annotate the JSP itself with <%@ page isErrorPage="true" %> and use the implicit exception object.
Servlet plays the controller (receives the request, calls the model, stores results as request attributes), business logic is the model (services/DAOs), and JSP is the view (renders attributes with EL/JSTL). The servlet forwards to the JSP with request.getRequestDispatcher("/view.jsp").forward(...), keeping logic out of the JSP.
Annotations (@WebServlet, @WebFilter, @WebListener, @MultipartConfig) are compiled into the class, are quick and local to the code. web.xml centralizes mapping, init params, welcome files, security constraints and error pages without recompiling. Since Servlet 3.0 both work; web.xml remains necessary for container-level settings.