I want to intercept a request in a filter/servlet and add a few parameters to it. However, the request does not expose a 'setParameter' method and the parameter map when manipulated throws an error saying it is locked. Is there an alternative I can try?
问题:
回答1:
Subclass HttpServletRequestWrapper
and override the getParameter
methods. The description of this class reads:
Provides a convenient implementation of the HttpServletRequest interface that can be subclassed by developers wishing to adapt the request to a Servlet.
In the filter, wrap the request in an instance of your subclass.
回答2:
I ussualy wrap the original HttpServletRequest into a new CustomHttpServletRequest that acts as a proxy to the original request and then pass this new CustomHttpServletRequest to the filter chain.
In this CustomHttpServletRequest you can overide the getParameterNames, getParameter, getParameterMap methods to return any parameters you want.
This is an example of the filter:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletRequest customRequest = new CustomHttpServletRequest(httpRequest);
customRequest.addParameter(xxx, "xxx");
chain.doFilter(customRequest, response);
}
回答3:
First you should receive the request and read all its parameters. Then construct another request with the original parameters + the new ones and send it again.
The HttpServletRequest is immutable and there is no way to change it.
回答4:
You can wrap HttpServletRequest into new HttpServletRequestWrapper object and overwrite some methods.
The following code is from http://www.ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/ .
To add parameter in filter:
public class MyFilter implements Filter {
...
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httprequest = (HttpServletRequest) request;
Map<String, String[]> extraParams = new HashMap<String, String[]>();
extraParams.put("myparamname", String[] { "myparamvalue" });
request = new WrappedRequestWithParameter(httprequest, extraParams);
}
chain.doFilter(request, response);
}
...
class WrappedRequestWithParameter extends HttpServletRequestWrapper {
private final Map<String, String[]> modifiableParameters;
private Map<String, String[]> allParameters = null;
public WrappedRequestWithParameter(final HttpServletRequest request, final Map<String, String[]> additionalParams) {
super(request);
modifiableParameters = new TreeMap<String, String[]>();
modifiableParameters.putAll(additionalParams);
}
@Override
public String getParameter(final String name) {
String[] strings = getParameterMap().get(name);
if (strings != null) {
return strings[0];
}
return super.getParameter(name);
}
@Override
public Map<String, String[]> getParameterMap() {
if (allParameters == null) {
allParameters = new TreeMap<String, String[]>();
allParameters.putAll(super.getParameterMap());
allParameters.putAll(modifiableParameters);
}
// Return an unmodifiable collection because we need to uphold the interface contract.
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);
}
}
}
回答5:
Why don't you just store variables as Request scope attributes instead of trying to append them to the request parameters?
回答6:
Otherwise, you can use the setAttribute() method which is strongly typed. Therefore, the getAttribute() method can be used ...