Creating a Basic Servlet
To begin learning Servlet development, we start with a simple Hello World example. Create a dynamic web project in you're IDE, then define a new Servlet class.
package com.example.demo;
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/HelloServlet")
public class GreetingServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html; charset=UTF-8");
PrintWriter writer = resp.getWriter();
try {
writer.println("<html>");
writer.println("<head><title>Greeting</title></head>");
writer.println("<body>");
writer.println("<h2>Hello World from Servlet</h2>");
writer.println("</body></html>");
} finally {
writer.close();
}
}
}
Configuring URL Patterns with Annotations
The @WebServlet annotation, introduced in Servlet 3.0, simplifies deployment by eliminating the need for web.xml configuration. It supports multiple URL patterns.
@WebServlet(
name = "MainServlet",
urlPatterns = {"/hello", "/greeting"}
)
public class MainServlet extends HttpServlet {
// Servlet implementation
}
Traditional Configuration via web.xml
For pre-3.0 environments or explicit configuration, you can define servlets in the deployment descriptor.
<servlet>
<servlet-name>DemoServlet</servlet-name>
<servlet-class>com.example.DemoServlet</servlet-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DemoServlet</servlet-name>
<url-pattern>/demo/*</url-pattern>
</servlet-mapping>
Accessing Configuration Parameters
Servlets can retrieve initialization parameters defined in web.xml or via annotations.
public class ConfigReaderServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Get servlet-specific init parameter
String encoding = getInitParameter("encoding");
// Get global context parameter
ServletContext context = getServletContext();
String imageTypes = context.getInitParameter("ImageType");
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<p>Encoding: " + encoding + "</p>");
out.println("<p>Allowed Image Types: " + imageTypes + "</p>");
}
}
Resource Injection with @Resource
Java EE provides dependency injection for resources defined in the deployment descriptor.
<env-entry>
<env-entry-name>welcomeMessage</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Welcome to the Application</env-entry-value>
</env-entry>
public class InjectedServlet extends HttpServlet {
@Resource(name = "welcomeMessage")
private String greetingText;
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().println(greetingText);
}
}
Servlet Lifecycle Annotations
The @PostConstruct and @PreDestroy annotations allow you to hook into the servlet lifecycle.
public class LifecycleServlet extends HttpServlet {
@PostConstruct
public void initialize() {
System.out.println("Servlet initialized - @PostConstruct");
}
@PreDestroy
public void cleanup() {
System.out.println("Servlet about to be destroyed - @PreDestroy");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().println("Lifecycle demo");
}
}
Request Dispatching and Redirection
Servlets can forward requests to other resources or redirect clients to different URLs.
public class NavigationServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Forward to another resource
RequestDispatcher dispatcher = req.getRequestDispatcher("/result.jsp");
dispatcher.forward(req, resp);
// Alternative: Redirect to external URL
// resp.sendRedirect("https://example.com");
}
}
Response Header Manipulation
You can control client behavior by setting specific HTTP headers.
public class HeaderServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Set refresh header for auto-redirect
resp.setHeader("Refresh", "5; URL=https://example.com");
// Alternative redirection method
resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
resp.setHeader("Location", "https://example.com");
resp.getWriter().println("Redirecting in 5 seconds...");
}
}
Thread Safety Considerations
Since servlets are typically multithreaded, avoid using instance variables for request-specific data to prevent concurrency issues.
public class ThreadSafeServlet extends HttpServlet {
// Unsafe: shared across all requests
// private int requestCount = 0;
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Safe: local variable for each request
int currentCount = 0;
// Process request
resp.getWriter().println("Request processed");
}
}