[java] How to set a parameter in a HttpServletRequest?

I am using a javax.servlet.http.HttpServletRequest to implement a web application.

I have no problem to get the parameter of a request using the getParameter method. However I don't know how to set a parameter in my request.

This question is related to java web-applications

The answer is


If you really want to do this, create an HttpServletRequestWrapper.

public class AddableHttpRequest extends HttpServletRequestWrapper {

   private HashMap params = new HashMap();

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

   public String getParameter(String name) {
           // if we added one, return that one
           if ( params.get( name ) != null ) {
                 return params.get( name );
           }
           // otherwise return what's in the original request
           HttpServletRequest req = (HttpServletRequest) super.getRequest();
           return validate( name, req.getParameter( name ) );
   }

   public void addParameter( String name, String value ) {
           params.put( name, value );
   }

}

As mentioned in the previous posts, using an HttpServletReqiestWrapper is the way to go, however the missed part in those posts was that apart from overriding the method getParameter(), you should also override other parameter related methods to produce a consistent response. e.g. the value of a param added by the custom request wrapper should also be included in the parameters map returned by the method getParameterMap(). Here is an example:

   public class AddableHttpRequest extends HttpServletRequestWrapper {

    /** A map containing additional request params this wrapper adds to the wrapped request */
    private final Map<String, String> params = new HashMap<>();

    /**
     * Constructs a request object wrapping the given request.
     * @throws java.lang.IllegalArgumentException if the request is null
     */
    AddableHttpRequest(final HttpServletRequest request) {
        super(request)
    }

    @Override
    public String getParameter(final String name) {
        // if we added one with the given name, return that one
        if ( params.get( name ) != null ) {
            return params.get( name );
        } else {
            // otherwise return what's in the original request
            return super.getParameter(name);
        }
    }


    /**
     * *** OVERRIDE THE METHODS BELOW TO REFLECT PARAMETERS ADDED BY THIS WRAPPER ****
     */

    @Override
    public Map<String, String> getParameterMap() {
        // defaulf impl, should be overridden for an approprivate map of request params
        return super.getParameterMap();
    }

    @Override
    public Enumeration<String> getParameterNames() {
        // defaulf impl, should be overridden for an approprivate map of request params names
        return super.getParameterNames();
    }

    @Override
    public String[] getParameterValues(final String name) {
        // defaulf impl, should be overridden for an approprivate map of request params values
        return super.getParameterValues(name);
    }
}

The most upvoted solution generally works but for Spring and/or Spring Boot, the values will not wire to parameters in controller methods annotated with @RequestParam unless you specifically implemented getParameterValues(). I combined the solution(s) here and from this blog:

import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MutableHttpRequest extends HttpServletRequestWrapper {

    private final Map<String, String[]> mutableParams = new HashMap<>();

    public MutableHttpRequest(final HttpServletRequest request) {
        super(request);
    }

    public MutableHttpRequest addParameter(String name, String value) {
        if (value != null)
            mutableParams.put(name, new String[] { value });

        return this;
    }

    @Override
    public String getParameter(final String name) {
        String[] values = getParameterMap().get(name);

        return Arrays.stream(values)
                .findFirst()
                .orElse(super.getParameter(name));
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> allParameters = new HashMap<>();
        allParameters.putAll(super.getParameterMap());
        allParameters.putAll(mutableParams);

        return Collections.unmodifiableMap(allParameters);
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(getParameterMap().keySet());
    }

    @Override
    public String[] getParameterValues(final String name) {
        return getParameterMap().get(name);
    }
}

note that this code is not super-optimized but it works.


Sorry, but why not use the following construction:

request.getParameterMap().put(parameterName, new String[] {parameterValue});

The missing getParameterMap override ended up being a real problem for me. So this is what I ended up with:

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/***
 * Request wrapper enabling the update of a request-parameter.
 * 
 * @author E.K. de Lang
 *
 */
final class HttpServletRequestReplaceParameterWrapper
    extends HttpServletRequestWrapper
{

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

    @SuppressWarnings("unchecked")
    HttpServletRequestReplaceParameterWrapper(HttpServletRequest request, String key, String value)
    {
        super(request);

        keyValues = new HashMap<String, String[]>();
        keyValues.putAll(request.getParameterMap());
        // Can override the values in the request
        keyValues.put(key, new String[] { value });

    }

    @SuppressWarnings("unchecked")
    HttpServletRequestReplaceParameterWrapper(HttpServletRequest request, Map<String, String> additionalRequestParameters)
    {
        super(request);
        keyValues = new HashMap<String, String[]>();
        keyValues.putAll(request.getParameterMap());
        for (Map.Entry<String, String> entry : additionalRequestParameters.entrySet()) {
            keyValues.put(entry.getKey(), new String[] { entry.getValue() });
        }

    }

    @Override
    public String getParameter(String name)
    {
        if (keyValues.containsKey(name)) {
            String[] strings = keyValues.get(name);
            if (strings == null || strings.length == 0) {
                return null;
            }
            else {
                return strings[0];
            }
        }
        else {
            // Just in case the request has some tricks of it's own.
            return super.getParameter(name);
        }
    }

    @Override
    public String[] getParameterValues(String name)
    {
        String[] value = this.keyValues.get(name);
        if (value == null) {
            // Just in case the request has some tricks of it's own.
            return super.getParameterValues(name);
        }
        else {
            return value;
        }
    }

    @Override
    public Map<String, String[]> getParameterMap()
    {
        return this.keyValues;
    }

}

From your question, I think what you are trying to do is to store something (an object, a string...) to foward it then to another servlet, using RequestDispatcher(). To do this you don't need to set a paramater but an attribute using

void setAttribute(String name, Object o);

and then

Object getAttribute(String name);