Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Tracking HTTP Request Lifecycle and Attribute Changes in Java Servlets

Tech 1

The Java Servlet specification provides event-driven mechanisms to observe state transitions within the HTTP request scope. Developers can monitor request object instantiation and termination, as well as track modifications to bound attributes, by implementing two core interfaces: ServletRequestListener and ServletRequestAttributeListener.

The ServletRequestListener interface intercepts the creation and disposal phases of a request object. Each time an HTTP request reaches the container, a new request instance is generated, triggering the initialization callback. When the container completes response processing or the request chain concludes, the instance is discarded, invoking the destruction callback.

The ServletRequestAttributeListener interface focuses specifically on data bound to the request object. It captures three distinct operations: introducing a new attribute, deleting an existing attribute, and overwriting the value associated with an existing key.

Consolidated Event Handler Implementation

A single class can implement both interfaces to centralize scope monitoring. The following implementation tracks lifecycle transitions and attribute mutations, using unique object references for clear console tracing.

package com.example.web;

import javax.servlet.*;
import javax.servlet.annotation.WebListener;

@WebListener
public class RequestScopeMonitor implements ServletRequestListener, ServletRequestAttributeListener {

    @Override
    public void requestInitialized(ServletRequestEvent evt) {
        ServletRequest activeReq = evt.getServletRequest();
        System.out.println("[Lifecycle] Request instance [" + System.identityHashCode(activeReq) + "] initialized.");
    }

    @Override
    public void requestDestroyed(ServletRequestEvent evt) {
        ServletRequest activeReq = evt.getServletRequest();
        System.out.println("[Lifecycle] Request instance [" + System.identityHashCode(activeReq) + "] terminated.");
    }

    @Override
    public void attributeAdded(ServletRequestAttributeEvent evt) {
        ServletRequest activeReq = evt.getServletRequest();
        String key = evt.getName();
        Object attachedVal = evt.getValue();
        System.out.println("[Attr] Bound '" + key + "'=" + attachedVal + " to request [" + System.identityHashCode(activeReq) + "].");
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent evt) {
        ServletRequest activeReq = evt.getServletRequest();
        String key = evt.getName();
        Object detachedVal = evt.getValue();
        System.out.println("[Attr] Unbound '" + key + "' (was " + detachedVal + ") from request [" + System.identityHashCode(activeReq) + "].");
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent evt) {
        ServletRequest activeReq = evt.getServletRequest();
        String key = evt.getName();
        Object previousVal = evt.getValue();
        Object updatedVal = activeReq.getAttribute(key);
        System.out.println("[Attr] Replaced '" + key + "' from " + previousVal + " to " + updatedVal + " in request [" + System.identityHashCode(activeReq) + "].");
    }
}

Lsitener Registration

Modern servlet containers automatically scan for the @WebListener annotation during deployment. Alternatively, explicit registration can be configured within the application's deployment descriptor.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                             http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <listener>
        <listener-class>com.example.web.RequestScopeMonitor</listener-class>
    </listener>
</web-app>

Triggering Scope Events

To validate the listener configuration, a basic HTTP servlet can be deployed to perform standard attribute operations during request handling.

package com.example.web;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/scope-test")
public class AttributeHandlerServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
        // Triggers attributeAdded callback
        req.setAttribute("session_flag", "active");
        
        // Triggers attributeReplaced callback
        req.setAttribute("session_flag", "verified");
        
        // Triggers attributeRemoved callback
        req.removeAttribute("session_flag");
        
        res.setContentType("text/plain");
        res.getWriter().write("Request scope listeners executed.");
    }
}

Dispatching a GET request to the /scope-test endpoint sequentially activates the registered callbacks, producing console output that reflects each intercepted lifecycle and data-binding operation.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.