Java Servlets

Manuranga Jayawardhana
14 min readMay 26, 2024

--

Introduction

Java Servlets are essential components for building dynamic web applications. They provide a way for web servers to handle user requests and generate responses, making it possible to create interactive and data-driven websites. This article will guide you through the basics of Java Servlets, including how they work, how to configure them, and practical examples to help you get started.

Contents

What is a Servlet?

  • Explanation of servlets and how they work with examples

HTTP Methods: GET and POST

  • Differences and usage in servlets

Calling a Servlet from Another Servlet

  • Using Request Dispatcher and Redirect methods with examples

Session Management

  • Explanation with a simple example

Cookies

  • Explanation with a simple example

ServletContext and ServletConfig

  • Purpose and usage with examples

Configuring with Annotations

  • Using annotations instead of XML with examples

Conclusion

  • Summary and motivation

By the end of this article, you will have a solid understanding of Java Servlets and be ready to implement them in your web projects. Let’s dive in!

What is a Servlet and How It Works

A servlet is a Java program that runs on a web server. It’s essentially a small application designed to handle requests and generate responses for web-based applications. Here’s a breakdown of what a servlet does and how it operates:

Dynamic webpage creation with servlets:

When a user requests a web page that is not prebuilt on the web server (a dynamic web page), the web server assigns this task to the web container. The web container then forwards the request to the appropriate servlet. The servlet processes the request by connecting to a database, retrieving necessary data, and generating dynamic content based on user inputs and database interactions. This dynamic content is then sent back to the web server, which delivers it to the user’s browser. Thus, servlets create dynamic web pages that can interact with user inputs and databases, ensuring real-time and customized web content.

Request Handling:

  • When a user sends a request (e.g., through a web form or by clicking a link), the web server passes this request to the appropriate servlet.
  • The servlet processes the request, which can include reading data sent by the user, interacting with a database, or performing other logic.

Generating Responses:

  • After processing the request, the servlet generates a response. This response could be an HTML page, JSON data, or any other format suitable for web communication.
  • The response is then sent back to the user’s browser.

Servlet Lifecycle:

  • Initialization: When the servlet is first created, its init method is called. This is where any one-time setup, like loading configuration settings, is done.
  • Service: For each request, the service method is called. This method determines the type of request (GET, POST, etc.) and calls the appropriate method (doGet, doPost, etc.) to handle it.
  • Destruction: When the servlet is no longer needed, the destroy method is called to clean up resources.

Efficiency of servlets:

  • Servlets are designed to handle multiple requests efficiently. A single instance of a servlet can handle many requests concurrently, reducing the overhead of creating new instances for each request.

Advantages of servlets:

  • Platform Independence: Written in Java, servlets are platform-independent, meaning they can run on any server that supports Java.
  • Integration: Servlets can easily integrate with other Java technologies like JDBC for database connectivity and JavaServer Pages (JSP) for dynamic web content.

For example:

The following HTML form allows users to input two numbers and submit them for addition. When the form is submitted, it sends a POST request to the “add” endpoint.

<!DOCTYPE html>
<html>
<head>
<title>Add Two Numbers</title>
</head>
<body>
<h1>Add Two Numbers</h1>
<form action="add" method="post">
<label for="num1">Number 1:</label>
<input type="text" id="num1" name="num1"><br><br>
<label for="num2">Number 2:</label>
<input type="text" id="num2" name="num2"><br><br>
<input type="submit" value="Add">
</form>
</body>
</html>

The following Java servlet code handles the POST request from the HTML form. It reads the two numbers, adds them, and sends back the result as an HTML response.

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/add")
public class addServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Get numbers from request
int num1 = Integer.parseInt(request.getParameter("num1"));
int num2 = Integer.parseInt(request.getParameter("num2"));

// Add numbers
int sum = num1 + num2;

// Set response content type
response.setContentType("text/html");

// Write response
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>Result: " + sum + "</h1>");
out.println("</body></html>");
}
}

Extending HttpServlet is crucial: This class equips our addServlet with handy methods tailored for handling HTTP requests and responses. It's like inheriting a set of tools specialized for web interactions, simplifying our job
HttpServletRequest and HttpServletResponse:When a user interacts with our servlet, their actions are encapsulated in a request object (HttpServletRequest). This object provides easy access to details like parameters and headers, essential for understanding what the user wants. On the flip side, HttpServletResponse handles our response back to the user. We use it to set things like content type and to send our result - in this case, the sum of two numbers - back to the user's browser. It's like crafting a tailored reply for each user interaction, ensuring a smooth web experience.

Here’s the configuration for the web.xml file that defines the servlet and its mapping:

    <servlet>
<servlet-name>addServlet</servlet-name>
<servlet-class>com.example.addServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>addServlet</servlet-name>
<url-pattern>/add</url-pattern>
</servlet-mapping>
</web-app>

Explanation of the configuration:

  • Servlet Declaration:

<servlet>: Defines the servlet with a name and the class that implements it

<servlet-name>: The name given to the servlet, used in the mapping.<servlet-class>: The fully qualified name of the servlet class.

  • Servlet Mapping:

<servlet-mapping>: Maps the servlet to a URL pattern.

<servlet-name>: Matches the servlet name defined earlier.

<url-pattern>: The URL pattern that triggers this servlet.

This configuration tells the webserver to use addServlet for requests sent to the /add URL.

get method and post method

In servlets, the GET and POST methods are crucial for handling different types of requests from clients.

GET Method:

  • Used for requests where parameters are appended to the URL.
  • Typically used for fetching data, like retrieving a webpage or an image.
  • In servlets, the doGet() method is employed to handle GET requests.

POST Method:

  • Utilized when sending data to the server, usually via forms or uploads.
  • Suitable for actions that may modify server-side data or trigger other operations.
  • In servlets, the doPost() method is employed to handle POST requests.
  • When we use a post request, the URL will not show the query that the use asked.

These methods, doGet() and doPost(), are implementations provided by the HttpServlet class. In a servlet, you override these methods to define the behaviour for handling GET and POST requests, respectively. Depending on the type of request your servlet expects and the actions it performs, you choose to implement doGet(), doPost(), or both. This allows servlets to effectively manage different types of interactions with clients, ensuring robust and flexible web applications.

Call a servlet from a servlet:

In servlets, there are two main methods for calling one servlet from another:

  1. Request Dispatcher:
  • This method is used when a servlet needs to call another servlet within the same web application.
  • It’s like asking for directions within the same neighbourhood.
  • The first servlet uses a request dispatcher to forward the request to the second servlet.
  • The second servlet then processes the request and sends a response back.

For example:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.RequestDispatcher;

public class FirstServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Some processing

// Forwarding the request to SecondServlet
RequestDispatcher dispatcher = request.getRequestDispatcher("/second");
dispatcher.forward(request, response);
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

public class SecondServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Handling the forwarded request

// Sending response
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h2>This is the Second Servlet</h2>");
out.println("</body></html>");
}
}

Explanation:

FirstServlet:

  • This servlet receives a GET request.
  • After some processing (which can be anything), it needs to call the SecondServlet.
  • It creates a RequestDispatcher object with the URL pattern of the SecondServlet.
  • The forward() method of the RequestDispatcher forwards the request and response objects to the SecondServlet.

SecondServlet:

  • This servlet receives the forwarded request from FirstServlet.
  • It processes the request as needed.
  • In this example, it simply sends a response back to the client’s browser, indicating that it has been reached.

2. Redirect:

  • Redirect is used when a servlet can’t directly forward the request to another servlet.
  • Instead, the servlet sends a response to the browser, telling it to go to a different web address.
  • It’s like giving someone a new address to visit when you can’t take them there yourself.
  • The browser receives this response and sends a new request to the specified web address, where another servlet handles the request.

Example:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FirstServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Some processing

// Redirecting to SecondServlet
response.sendRedirect("second");
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

public class SecondServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Handling the redirected request

// Sending response
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h2>This is the Second Servlet</h2>");
out.println("</body></html>");
}
}

Explanation:

FirstServlet:

  • This servlet receives a GET request.
  • After some processing (which can be anything), it needs to redirect the request to SecondServlet.
  • It calls response.sendRedirect("second") to inform the browser to send a new request to the URL pattern "second".

SecondServlet:

  • This servlet receives the redirected request from FirstServlet.
  • It processes the request as needed.
  • In this example, it simply sends a response back to the client’s browser, indicating that it has been reached.

These methods provide flexibility in how servlets communicate with each other, whether it’s within the same web application or across different web addresses.

Redirecting with addServlet:

By the addServlet, a response is sent to the browser by redirecting the browser. This can be done in three ways:

  1. URL rewriting
  2. Session management
  3. Cookie

Now let’s study these one by one.

  1. URL rewriting

URL Rewriting is a technique used to maintain session information by including session data directly in the URL. This is useful when cookies are disabled on the client side.
When a user interacts with a web application, the server often needs to keep track of the user’s session. URL rewriting achieves this by appending session information as a query parameter to the URL. This way, every time the user clicks a link or submits a form, the session information is sent along with the request.

Example:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FirstServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Some processing

// Retrieve the session ID
String sessionId = request.getSession().getId();

// Redirecting to SecondServlet with session ID
response.sendRedirect("second?sessionId=" + sessionId);
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FirstServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Some processing

// Retrieve the session ID
String sessionId = request.getSession().getId();

// Redirecting to SecondServlet with session ID
response.sendRedirect("second?sessionId=" + sessionId);
}
}

Explanation:

FirstServlet:

  • This servlet handles a GET request.
  • It retrieves the current session ID using request.getSession().getId().
  • It then redirects to SecondServlet, appending the session ID to the URL (second?sessionId=" + sessionId).

SecondServlet:

  • This servlet handles the redirected request.
  • It retrieves the session ID from the URL using request.getParameter("sessionId").
  • It uses this session ID as needed and sends a response back to the client, displaying the session ID and a message.

URL rewriting ensures that session information is passed along with each request, even when cookies are not available, enabling the server to maintain the user’s session seamlessly.

2. Session management

Session Management is a way to keep track of a user’s interactions with a web application over multiple requests. This helps the server remember the user’s information, like login status or items in a shopping cart, during a session.
When a user visits a website, the server creates a unique session for them. This session is stored on the server and has a unique ID, which is usually sent to the user’s browser as a cookie. The browser sends this session ID back to the server with each request, allowing the server to retrieve the stored information and maintain continuity.

Example:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Simulate a user login
String username = request.getParameter("username");

// Create a session and set an attribute
HttpSession session = request.getSession();
session.setAttribute("username", username);

// Redirect to the welcome page
response.sendRedirect("welcome");
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;

public class WelcomeServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Retrieve the session
HttpSession session = request.getSession(false);
String username = null;

if (session != null) {
// Get the username from the session
username = (String) session.getAttribute("username");
}

// Sending response
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
if (username != null) {
out.println("<h2>Welcome, " + username + "!</h2>");
} else {
out.println("<h2>Welcome, Guest!</h2>");
}
out.println("</body></html>");
}
}

Explanation:

LoginServlet:

  • This servlet handles a POST request when a user logs in.
  • It retrieves the username from the request.
  • It creates a session using request.getSession(), then stores the username in the session.
  • Finally, it redirects the user to the welcome page (WelcomeServlet).

WelcomeServlet:

  • This servlet handles a GET request when the user is redirected.
  • It retrieves the existing session using request.getSession(false). The false parameter prevents creating a new session if one doesn't exist.
  • It retrieves the username from the session, if available.
  • It sends a response back to the client, displaying a welcome message with the username if the user is logged in, or a generic welcome message if not.

Session management helps maintain user-specific data across multiple requests, ensuring a smooth and personalized user experience on the web.

3. Cookie

Cookies are small pieces of data stored on the user’s browser. They help the server remember information about the user between different requests, such as preferences, login status, or other session data.
When a user visits a website, the server can send a cookie to the user’s browser. This cookie is stored on the user’s device and sent back to the server with each subsequent request. This way, the server can remember important information about the user and provide a consistent experience.

Example:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SetCookieServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Create a new cookie
Cookie userCookie = new Cookie("username", "JohnDoe");

// Set the cookie to expire in 24 hours (86400 seconds)
userCookie.setMaxAge(86400);

// Add the cookie to the response
response.addCookie(userCookie);

// Inform the user
response.setContentType("text/html");
response.getWriter().println("<html><body>");
response.getWriter().println("<h2>Cookie has been set!</h2>");
response.getWriter().println("</body></html>");
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

public class GetCookieServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Get cookies from the request
Cookie[] cookies = request.getCookies();
String username = "Guest";

// Find the specific cookie
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("username")) {
username = cookie.getValue();
break;
}
}
}

// Sending response
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h2>Welcome, " + username + "!</h2>");
out.println("</body></html>");
}
}

Explanation:

SetCookieServlet:

  • This servlet handles a GET request.
  • It creates a new cookie named “username” with the value “JohnDoe”.
  • The cookie is set to expire in 24 hours using setMaxAge(86400).
  • The cookie is added to the response using response.addCookie(userCookie).
  • The servlet informs the user that the cookie has been set.

GetCookieServlet:

  • This servlet handles a GET request.
  • It retrieves all cookies from the request using request.getCookies().
  • It searches for a cookie named “username”.
  • If the cookie is found, it retrieves its value; otherwise, it defaults to “Guest”.
  • The servlet sends a response back to the client, displaying a welcome message with the username from the cookie or a generic welcome message if the cookie is not found.

Cookies allow web applications to store small pieces of data on the client’s browser, helping maintain user information and preferences across multiple visits.

Servlet context and Servlet config

ServletContext and ServletConfig are used for initial setup in servlets, allowing you to specify parameters such as file paths, usernames, passwords, and more.

ServletContext:

  • Used to set initial values that need to be shared across multiple servlets within the web application.
  • For example, you can define a database URL or a common file directory that all servlets can access.
  • It acts as a global storage area accessible to all servlets.

ServletConfig:

  • Used to set initial values specific to a single servlet.
  • For example, you might define a specific configuration for just one servlet, like a custom setting or a servlet-specific file path.
  • It allows each servlet to have its own unique setup.

Both ServletContext and ServletConfig are interfaces that provide these functionalities, ensuring that initial parameters are properly set up and accessible as needed.

Example:

<web-app>
<!-- Context parameters -->
<context-param>
<param-name>globalEmail</param-name>
<param-value>admin@example.com</param-value>
</context-param>

<!-- Servlet Configuration for MyServlet -->
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
<!-- Config parameters for MyServlet -->
<init-param>
<param-name>servletName</param-name>
<param-value>MyFirstServlet</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
</web-app>
package com.example;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletContext;
import javax.servlet.ServletConfig;
import java.io.PrintWriter;

public class MyServlet extends HttpServlet {
private String servletName;

@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
// Accessing servlet-specific init parameter
servletName = config.getInitParameter("servletName");
}

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Accessing context parameter
ServletContext context = getServletContext();
String globalEmail = context.getInitParameter("globalEmail");

// Sending response
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h2>Servlet Name: " + servletName + "</h2>");
out.println("<h2>Global Email (from ServletContext): " + globalEmail + "</h2>");
out.println("</body></html>");
}
}

Explanation:

web.xml:

  • Context parameters: Defined using the context-param tag, these parameters are available to all servlets within the web application. In this example, the parameter globalEmail is set to "admin@example.com".
  • Servlet parameters: Defined within the servlet tag for a specific servlet. Here, MyServlet has an init parameter servletName set to "MyFirstServlet".

MyServlet.java:

  • init method: This method initializes the servlet and retrieves the servlet-specific parameter using config.getInitParameter("servletName"). This allows MyServlet to use the parameter servletName defined in the web.xml.
  • doGet method:
  • The ServletContext is obtained using getServletContext(), allowing the servlet to access the context parameter globalEmail.
  • The servlet then generates an HTML response that includes both the servlet-specific parameter (servletName) and the context parameter (globalEmail).

In this simple example, you can see how ServletContext and ServletConfig are used to provide initial setup values for servlets. ServletContext parameters are shared across all servlets in the application, while ServletConfig parameters are specific to each individual servlet. This setup allows for flexible configuration and easy access to common and specific parameters within your servlets.

Configuring a web application using Annotation

There are two ways to configure a web application:

  1. Using XML
  2. Using Annotations

Until now, we used XML to configure the web app. Instead of using XML, we can also use annotations to configure the web app. Using annotations is often easier because it allows you to define configurations directly in the code without the need for a separate XML file.

For example, when the browser calls a servlet with the URL pattern /my, the servlet with the annotation @WebServlet("/my") will be called.

package com.example;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;
import java.io.PrintWriter;

@WebServlet("/my")
public class ExampleServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Sending response
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h2>This servlet is configured using annotations!</h2>");
out.println("</body></html>");
}
}
  • The @WebServlet annotation is used to map the servlet to a specific URL pattern.
  • In this example, the ExampleServlet is mapped to the URL pattern /my.
  • When the browser makes a request to /my, the servlet with the @WebServlet("/my") annotation is called.
  • This eliminates the need for XML configuration, making the setup simpler and more integrated with the servlet code.

Using annotations is a modern and convenient way to configure servlets, making your web application setup cleaner and easier to manage.

Conclusion

Java Servlets are a powerful tool for creating dynamic web applications. From handling requests and generating responses to managing sessions and maintaining user data, servlets offer a robust framework for web development. Whether you configure your servlets using XML or take advantage of the simplicity of annotations, understanding the core concepts of servlets will greatly enhance your ability to build efficient and scalable web applications.

Embrace the flexibility and power of Java Servlets to create innovative solutions and deliver exceptional web experiences. As you continue to explore and master these technologies, you’ll find yourself well-equipped to tackle the challenges of modern web development. Keep learning, keep coding, and let your creativity drive your success in the world of web applications.

--

--

Manuranga Jayawardhana

B.Sc. Computer Engineering undergraduate @ University of Jaffna. Writing about SE, ML, blockchain, deep learning, & AI. Passionate about tech!