How do I configure servlets in web.xml?

In a Jakarta EE (formerly Java EE) application, you can configure servlets in the web.xml deployment descriptor. The web.xml file is located in the WEB-INF directory of your project. Here’s how you can configure a servlet in web.xml step-by-step:

1. Declare the Servlet

You define the servlet by giving it a name and specifying its implementing class.

<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>org.kodejava.servlet.MyServlet</servlet-class>
</servlet>

2. Map the Servlet to a URL Pattern

After declaring the servlet, you specify the URL patterns (endpoints) it should handle.

<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/myServlet</url-pattern>
</servlet-mapping>

The servlet-name in the <servlet-mapping> must match the one defined in the <servlet> section.

Complete Example

Below is a complete example of web.xml configuration for a servlet:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
         version="6.0">

    <!-- Declare the servlet -->
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>org.kodejava.servlet.MyServlet</servlet-class>
    </servlet>

    <!-- Map the servlet to a URL pattern -->
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/myServlet</url-pattern>
    </servlet-mapping>

</web-app>

Understanding the Tags

  • <servlet>: Declares the servlet, including its name and fully qualified class name.
  • <servlet-name>: A unique name for your servlet (used in <servlet-mapping> to link configuration).
  • <servlet-class>: The fully qualified class name of the servlet (e.g., org.kodejava.servlet.MyServlet).
  • <servlet-mapping>: Maps the declared servlet to specific URL patterns (e.g., /myServlet).
  • <url-pattern>: Specifies the URL or set of URLs that the servlet will handle.

Notes:

  1. URL Patterns:
    • /myServlet matches a specific path.
    • /* matches all paths.
    • /example/* matches all paths under /example.
  2. Multiple Servlet Mappings: You can map the same servlet to multiple URL patterns by adding multiple <servlet-mapping> entries.

  3. Override Annotations: If you use @WebServlet annotations in your servlet class, you generally won’t need to configure the servlet in web.xml. However, web.xml still allows more control over deployment and compatibility with older specifications.
  4. Jakarta EE Web.xml Version:
    The <web-app> version should match the Jakarta EE version you are using. For Jakarta EE 10, use version="6.0" as shown above.

How do I include content from another servlet or JSP?

To include the content of one servlet or JSP into another, you can use the functionality provided by the RequestDispatcher interface in Jakarta Servlet (previously Javax Servlet). The two primary methods for including content are:

  1. Using RequestDispatcher.include():
    This method includes the response of another servlet or JSP within the response of the current servlet or JSP.

  2. Using <jsp:include /> Tag:
    This is specifically used in JSP to include another JSP or servlet dynamically.


1. Using RequestDispatcher.include() in servlets

You can use the include() method of the RequestDispatcher to include the content of another servlet or JSP. Here’s how it works:

  • Steps:
    1. Obtain a RequestDispatcher object for the target servlet or JSP.
    2. Use the include() method to include its output.

Example Code:

package org.kodejava.servlet;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;

import java.io.IOException;

@WebServlet("/include")
public class IncludeServletExample extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        var out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1>Content from Main Servlet</h1>");

        // Getting RequestDispatcher for another servlet or JSP
        RequestDispatcher dispatcher = request.getRequestDispatcher("/example");

        // Including content
        dispatcher.include(request, response);

        out.println("<h1>This is after including the content</h1>");
        out.println("</body></html>");
    }
}

2. Using <jsp:include /> in JSP

This is used to include either static or dynamic content from another JSP or servlet directly within a JSP page.

  • Syntax:
<jsp:include page="URL or Path" />

The page attribute specifies the relative URL or path of the servlet or JSP to be included.

Example Code:

<html>
<body>
  <h1>Content from Main JSP</h1>

  <!-- Include another servlet or JSP -->
  <jsp:include page="includedJspPage.jsp" />

  <h1>This is after including the content</h1>
</body>
</html>

Important Notes

  • Differences between include() and forward():
    • include(): Includes the response from the target servlet/JSP into the current response. The execution continues after including the content.
    • forward(): Forwards the request to another servlet/JSP. The control does not return to the original servlet/JSP.
  • Context-relative paths:
    • When specifying the path in RequestDispatcher (e.g., /example), always use context-relative paths (starting with a / relative to the root of the web application).
  • Dynamic Content:
    • The target servlet or JSP can contain dynamic content, as it is executed when included.

Maven dependencies

<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.1.0</version>
    <scope>provided</scope>
</dependency>

Maven Central

How do I create a servlet filter to make secure cookies?

The CookieFilter class in this example is a servlet filter. Servlet filters in Java web applications are used to perform tasks such as request/response modification, authentication, logging, and more. In the context of managing cookies, a CookieFilter can be used to intercept requests and responses to handle cookie-related operations, such as setting secure attributes on cookies or checking cookie values for authentication purposes.

Here’s an example of how you can implement a CookieFilter class in Java:

package org.kodejava.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebFilter("/*")
public class CookieFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // Initialization code, if needed
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        // Check if a session exists
        HttpSession session = httpRequest.getSession(false);
        if (session != null) {
            // Example: Set secure attribute on session cookie
            sessionCookieSecure(httpRequest, httpResponse);
        }

        // Continue the request chain
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // Cleanup code, if needed
    }

    private void sessionCookieSecure(HttpServletRequest request, HttpServletResponse response) {
        // Assuming the session cookie name
        String cookieName = "JSESSIONID"; 
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(cookieName)) {
                    // Set the secure attribute on the session cookie
                    cookie.setSecure(true);
                    // Update the cookie in the response
                    response.addCookie(cookie); 
                    break;
                }
            }
        }
    }
}

In this example:

  • The CookieFilter class implements the Filter interface, which requires implementing methods like init, doFilter, and destroy.
  • Inside the doFilter method, it checks if a session exists for the incoming request.
  • If a session exists, it calls the sessionCookieSecure method to set the secure attribute on the session cookie.
  • The sessionCookieSecure method iterates through cookies in the request, finds the session cookie (e.g., JSESSIONID), and sets its secure attribute to true.

You can modify this filter implementation based on your specific cookie management requirements, such as setting secure attributes on specific cookies or performing additional cookie-related tasks.

How do I configure secure cookies using web.xml?

To configure secure cookies using web.xml, you typically need to set the secure attribute on your cookie definitions. This ensures that the cookie is only sent over HTTPS connections, enhancing security by protecting sensitive information from being transmitted over unencrypted channels. Here’s how you can do it:

1. Define Your Servlet Filter (Optional but Recommended):

If you don’t have a servlet filter for managing cookies, you can create one. This filter can intercept requests and responses to handle cookie-related operations.

<filter>
    <filter-name>CookieFilter</filter-name>
    <filter-class>org.kodejava.servlet.CookieFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CookieFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Replace org.kodejava.servlet.CookieFilter with the actual class that implements your cookie handling logic.

2. Configure Secure Cookie in web.xml:

Inside your web.xml, you can define cookie configurations using <session-config> and <cookie-config> elements.

<session-config>
   <cookie-config>
      <!-- Recommended to prevent client-side script access -->
      <http-only>true</http-only>
      <!-- Set all cookies to be secure -->
      <secure>true</secure>
    </cookie-config>
</session-config>
  • <secure>true</secure>: This line ensures that all cookies are marked as secure, meaning they will only be sent over HTTPS connections.
  • <http-only>true</http-only>: This line makes cookies accessible only through HTTP headers, preventing client-side scripts (like JavaScript) from accessing them. It adds another layer of security against certain types of attacks.

3. Deploy and Test:

After making these changes, deploy your web application and test it over HTTPS. Verify that cookies are being set with the secure flag by checking your browser’s developer tools (usually under the “Application” or “Storage” tab).

By following these steps, you can configure secure cookies in your Java web application using web.xml.

Notes: Setting the secure attribute in web.xml configures the default behavior for cookies created by the servlet container. However, for custom cookies that your application creates programmatically, you need to explicitly call setSecure(true) on the Cookie object to make them secure.

How do I delete a cookie in Servlet?

The Servlet API doesn’t provide a direct way to delete a cookie in a Servlet application. If you want to delete a cookie you have to create a cookie that have the same name with the cookie that you want to delete and set the value to an empty string. You also need to set the max age of the cookie to 0. And then add this cookie to the servlet’s response object.

Let’s see the code example below:

package org.kodejava.servlet;

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

@WebServlet(name = "DeleteCookieServlet", urlPatterns = "/deleteCookie")
public class DeleteCookieServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //
        // To delete a cookie, we need to create a cookie that have the same
        // name with the cookie that we want to delete. We also need to set
        // the max age of the cookie to 0 and then add it to the Servlet's
        // response method.
        //
        Cookie cookie = new Cookie("username", "");
        cookie.setMaxAge(0);
        response.addCookie(cookie);
    }
}

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central