Enterprise Java

Set a parameter in a Java HttpServletRequest

The HttpServletRequest interface in Java is a fundamental part of Jakarta Servlets formerly Java Servlets, providing a way for servlets to interact with client requests. The ability to intercept and modify incoming HTTP requests before they reach the application holds significant value. Filters provide an elegant solution to preprocess these requests dynamically. In this article, we will delve into the creation of a filter that intercepts an HttpServletRequest, leveraging a custom HttpServletRequestWrapper for parameter sanitization. The ultimate goal is to showcase how such a filter can enrich the request with custom parameters, providing an understanding of its applications in building robust web applications.

1. Understanding HttpServletRequest, HttpServletRequestWrapper, and Filters

Before getting involved in setting parameters, let’s briefly understand the HttpServletRequest interface and the concept of Parameters, HttpServletRequestWrapper, and Filters.

1.1 HttpServletRequest Interface

The HttpServletRequest interface is part of the Java Servlet API and is used to represent an HTTP request made by a client. It provides methods to obtain information about the request, such as headers, parameters, and session details.

We utilize HttpServletRequest to engage with client requests and customize our servlets accordingly.

1.2 Parameters

Parameters are key-value pairs sent by clients in the HTTP request. These can be part of the query string in the URL for GET requests or included in the request body for POST requests. Servlets use parameters to retrieve client data and perform necessary actions.

1.3 HttpServletRequestWrapper

As we navigate the intricacies of request processing, we might encounter scenarios demanding modification of the original request. HttpServletRequestWrapper is a powerful class that extends HttpServletRequest to facilitate dynamic modification.

This wrapper empowers us to customize request objects, dynamically altering their behavior. We can create a custom HttpServletRequestWrapper for tasks such as parameter sanitization.

1.4 Filters

Filters are components that provide a mechanism to intercept and process requests and responses as they pass through the servlet container. Filters sit between the client’s request and the servlet, allowing us to perform pre-processing and post-processing tasks on a request, a response, or both.

Multiple filters can be chained together to create a sequence of processing steps. Each filter in the chain can contribute to the overall processing of the request and response. Filters have a defined lifecycle with methods like init, doFilter, and destroy, allowing us to initialize resources, perform filtering logic, and release resources when the filter is no longer needed.

2. Maven Dependencies

For our servlet-based web application, we need to include the dependencies related to the Java Servlet API and Jetty Servlet container. We can achieve this by adding the following entries to the <dependencies> section of the pom.xml file:

<dependencies>
        <!-- Servlet API -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

        <!-- Jetty Servlet Container -->
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.4.43.v20210629</version>
        </dependency>

        <!-- Jetty Servlet API -->
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>9.4.43.v20210629</version>
        </dependency>
</dependencies>

3. Example: Parameter Sanitization

Filters empower us to sanitize incoming parameters, guarding against injection attacks and ensuring data integrity. In the context of parameter sanitization, filters assume the role of protectors, carefully inspecting and purifying incoming parameters.

In this example, we explore the Filter interface and its lifecycle, delving into the creation of a filter dedicated to parameter sanitization. We will also observe how filters complement HttpServletRequest and HttpServletRequestWrapper.

3.1 Create SanitizedRequestWrapper

Let’s update the application to use HttpServletRequestWrapper to sanitize the request parameters. We will create a custom wrapper class named SanitizedRequestWrapper to override the getParameter method and sanitize the parameter values. The filter will then use this wrapper to process the incoming request.

public class SanitizedRequestWrapper extends HttpServletRequestWrapper {

    public SanitizedRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        // Override the getParameter method to sanitize parameter values
        String originalValue = super.getParameter(name);
        return sanitize(originalValue);
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        // Override getParameterMap to sanitize all parameter values
        return super.getParameterMap().entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> sanitize(entry.getValue())));
    }

    private String[] sanitize(String[] values) {
        // Sanitize each value in the array
        return Arrays.stream(values).map(this::sanitize).toArray(String[]::new);
    }

    private String sanitize(String value) {
        // Implement your sanitization logic here
        // For simplicity, let's say we're removing any digits from the parameter values
        return value.replaceAll("\\d", "");
    }
}

Here is a break down the key elements of this code:

  • Constructor: public SanitizedRequestWrapper(HttpServletRequest request) constructor takes an HttpServletRequest as a parameter and calls the constructor of the superclass (HttpServletRequestWrapper) with the provided request. This establishes the connection between the wrapper and the original request.
  • Overridden getParameter Method: This method overrides the getParameter method from the superclass. It calls the original getParameter method to retrieve the parameter value. The retrieved value is then passed to the sanitize method, which performs the sanitization logic.
  • Overridden getParameterMap Method: This method overrides the getParameterMap method from the superclass. It retrieves the original parameter map using super.getParameterMap(). It uses Java Stream API to iterate over the entries of the map and applies the sanitize method to each array of values. The sanitized map is then returned.
  • sanitize Methods: These methods perform the actual sanitization.
    • The sanitize(String[]) method uses Java Streams to sanitize each value in the array.
    • The sanitize(String) method, in this example, removes any digits from the parameter values using a regular expression

3.2 Create a ParameterSettingFilter to use SanitizedRequestWrapper

@WebFilter(filterName = "ParameterSettingFilter", urlPatterns = {"/*"})
public class ParameterSettingFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        // Wrap the request with the SanitizedRequestWrapper
        HttpServletRequest sanitizedRequest = new SanitizedRequestWrapper((HttpServletRequest) request);

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

}

Here, we create a filter that intercepts the incoming request. We use the doFilter method in the ParameterSettingFilter to wrap the original request with SanitizedRequestWrapper. This ensures that the sanitized request will be used downstream.

3.3 Create a Servlet to Access the Parameter

Next, create a servlet to access the newly added parameters.

@WebServlet(name = "DisplayParametersServlet", urlPatterns = {"/displayparams"})
public class DisplayParametersServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        SanitizedRequestWrapper sanitizedRequest = new SanitizedRequestWrapper(req);

        // Retrieve sanitized parameter values
        String sanitizedParam = sanitizedRequest.getParameter("userInput");

        // Output the sanitized parameter value
        resp.setContentType("text/plain");
        resp.getWriter().println("");
        resp.getWriter().println("Sanitize Parameters Example");
        resp.getWriter().write("Sanitized Parameter Value: " + sanitizedParam);
        resp.getWriter().println("");
    }
}

In this servlet, An instance of the SanitizedRequestWrapper class is created by passing the original HttpServletRequest (req) to its constructor. This SanitizedRequestWrapper is used to retrieve a parameter called userInput, and the sanitized value is then outputted to the response.

To test the servlet, we need to deploy this servlet in our servlet container (in this article – Eclipse Jetty) and access it through a web browser or a tool like cURL.

To test the servlet using cURL, we can make a GET request and observe the response. Here’s an example cURL command:

curl http://localhost:8080/displayparams?userInput=123abc456def

This command sends a GET request to the specified URL with a query parameter named userInput. The provided value is 123abc456def. The servlet, in turn, processes this request and uses the SanitizedRequestWrapper to retrieve and sanitize the parameter value.

The output is:

Fig 1: sanitized output from java servlet request set parameter example
Fig 1: sanitized output from java servlet request set parameter example

The output when we access the servlet URL on a web browser at http://localhost:8080/displayparams?userInput=123abc456def is:

Fig 2: Sanitized output on a web browser
Fig 2: Sanitized output on a web browser

4. Modify Request Parameters: Adding and Removing in Action

To demonstrate adding a new parameter and removing one from the original request, we need to modify/enhance the code.

Create a new class named EnhancedRequestWrapper that extends the HttpServletRequestWrapper with the following code:

4.1 EnhancedRequestWrapper Class

public class EnhancedRequestWrapper extends HttpServletRequestWrapper {

    private final Map<String, String[]> modifiedParameters;

    public EnhancedRequestWrapper(HttpServletRequest request) {
        super(request);
        this.modifiedParameters = new HashMap<>(request.getParameterMap());
        
        // Adding a new parameter
        this.modifiedParameters.put("newParameter", new String[]{"javacodegeeks"});

        // Removing an existing parameter
        this.modifiedParameters.remove("userInput");

    }

    @Override
    public String getParameter(String name) {
        // Retrieve the parameter from the modified parameters
        String[] values = modifiedParameters.get(name);
        return (values != null && values.length > 0) ? values[0] : null;
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        // Return an unmodifiable map to prevent modification
        return Collections.unmodifiableMap(modifiedParameters);
    }

    @Override
    public Enumeration<String> getParameterNames() {
        // Return enumeration of parameter names
        return Collections.enumeration(modifiedParameters.keySet());
    }

    @Override
    public String[] getParameterValues(String name) {
        // Retrieve the parameter values from the modified parameters
        return modifiedParameters.get(name);
    }
}

In this modification, we added a new parameter named newParameter with a value of javacodegeeks and removed the existing userInput parameter from the original request. The get methods are updated to retrieve parameters from the modified set.

We can use this enhanced wrapper EnhancedRequestWrapper in our servlet just as before. The servlet code remains the same:

@WebServlet(name = "DisplayParametersServlet", urlPatterns = {"/displayparams"})
public class DisplayParametersServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // Creating an instance of EnhancedRequestWrapper to sanitize and modify parameters
        EnhancedRequestWrapper enhancedRequest = new EnhancedRequestWrapper(req);

        // Retrieve parameters
        String newParamValue = enhancedRequest.getParameter("newParameter");
        String removedParamValue = enhancedRequest.getParameter("userInput");

        // Output the parameters
        resp.setContentType("text/plain");
        resp.getWriter().println("");
        resp.getWriter().println("Enhanced Request Parameters Example");
        resp.getWriter().write("New Parameter Value: " + newParamValue);
        resp.getWriter().println("");
        resp.getWriter().write("Removed Parameter Value: " + removedParamValue);
        resp.getWriter().println("");
    }
}

4.2 Modify ParameterSettingFilter to use EnhancedRequestWrapper

Next, we need to modify the doFilter method in the ParameterSettingFilter to wrap the original request with EnhancedRequestWrapper.

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
    
        HttpServletRequest enhancedRequest = new EnhancedRequestWrapper((HttpServletRequest) request);

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

4.3 Access the Servlet and Inspect the Output

To use cURL to make a simple GET request to the servlet, assuming the servlet is running on http://localhost:8080/displayparams, we can use the following command:

curl http://localhost:8080/displayparams?userInput=modifyparameters

Now, when we access the servlet, we should see the output reflecting the addition of the new parameter and the removal of the existing one. The servlet is configured to output parameter values, including the new parameter and the removed parameter. The example output is:

Enhanced Request Parameters Example
New Parameter Value: javacodegeeks
Removed Parameter Value: null

5. Conclusion

In this article, we explored key Servlet components essential for Java web application development to manage incoming client requests. These components include:

  • HttpServletRequest: The central stage, where information from the client’s browser arrives – parameters, headers, cookies, and more.
  • HttpServletRequestWrapper: Wrapping the request to fit your specific needs – modifying and adding parameters.
  • Filter: Used for intercepting requests before they reach their destination, filtering sensitive information, performing validations, or redirecting traffic.

6. Download the Source Code

This was an example of how to set parameter in a Java servlet request.

Download
You can download the full source code of this example here: java servlet request set parameter

Omozegie Aziegbe

Omos holds a Master degree in Information Engineering with Network Management from the Robert Gordon University, Aberdeen. Omos is currently a freelance web/application developer who is currently focused on developing Java enterprise applications with the Jakarta EE framework.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button