【问题标题】:Is it possible to add to the available parameters of a request (HttpServletRequest)是否可以添加到请求的可用参数(HttpServletRequest)
【发布时间】:2010-09-16 11:47:36
【问题描述】:

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

【问题讨论】:

    标签: java http servlets


    【解决方案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);
        }
    }
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我将其添加为修改常规请求的属性文件驱动机制。 UI 和实际的 servlet 都无法更改以适应这些要求 - 它是透明的。
      【解决方案3】:

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

      【讨论】:

      • 我将其添加为属性文件驱动的机制,用于修改常规请求。 UI 和实际的 servlet 都不能更改以适应这些要求 - 它是透明的。
      【解决方案4】:

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

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

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

      【讨论】:

      • 你能举个例子吗?
      • 公共类 CustomHttpServletRequestWrapper 扩展 HttpServletRequestWrapper { private Map customParameters;公共CustomHttpServletRequestWrapper(HttpServletRequest请求){超级(请求); } public void addCustomParameter(String name, String value) { customParameters.put(name, value); } @Override public String getParameter(String name) { String originalParameter = super.getParameter(name); if (originalParameter != null) { return originalParameter; } else { 返回 customParameters.get(name); } } }
      【解决方案5】:

      我通常将原始 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);
      }
      

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          猜你喜欢
          • 2019-12-07
          • 2012-11-06
          • 2018-09-05
          • 1970-01-01
          • 2020-02-21
          • 2014-08-16
          • 2023-04-09
          • 2016-11-16
          • 2019-08-03
          相关资源
          最近更新 更多