10

我想在过滤器/servlet 中拦截一个请求并添加一些参数。但是,该请求没有公开“setParameter”方法,并且在操作参数映射时会抛出一个错误,说明它已被锁定。有没有我可以尝试的替代方案?

4

6 回答 6

13

子类HttpServletRequestWrapper化并覆盖getParameter方法。这个类的描述如下:

提供 HttpServletRequest 接口的便捷实现,希望将请求适应 Servlet 的开发人员可以将其子类化。

在过滤器中,将请求包装在子类的实例中。

于 2008-10-10T11:12:34.177 回答
6

我通常将原始 HttpServletRequest 包装到一个新的 CustomHttpServletRequest 中,它充当原始请求的代理,然后将这个新的 CustomHttpServletRequest 传递给过滤器链。

在此 CustomHttpServletRequest 中,您可以覆盖 getParameterNames、getParameter、getParameterMap 方法以返回您想要的任何参数。

这是过滤器的示例:

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);
}
于 2008-10-10T11:10:08.673 回答
1

首先,您应该收到请求并读取其所有参数。然后用原始参数+新参数构造另一个请求并再次发送。

HttpServletRequest 是不可变的,没有办法改变它。

于 2008-10-10T11:08:33.513 回答
1

您可以将 HttpServletRequest 包装到新的 HttpServletRequestWrapper 对象中并覆盖一些方法。

以下代码来自http://www.ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/

在过滤器中添加参数:

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);
    }
}
}
于 2015-11-12T17:11:45.617 回答
0

为什么不将变量存储为请求范围属性,而不是尝试将它们附加到请求参数?

于 2008-10-12T13:32:08.297 回答
-1

否则,您可以使用强类型的 setAttribute() 方法。因此,可以使用 getAttribute() 方法...

于 2008-10-10T12:48:22.397 回答