是否可以在不消耗流的情况下读取Http Request参数?

时间:2012-04-26 16:02:12

标签: java servlets servlet-filters

我正在查看sitebricks here中HiddenMethodFilter的实现:

在第65行,有以下代码:

try {
    String methodName = httpRequest.getParameter(this.hiddenFieldName);
    if ("POST".equalsIgnoreCase(httpRequest.getMethod()) && !Strings.empty(methodName)) {
    ....

它检查是否设置了特定参数并使用它来包装请求。但是,在读取该参数时,它将使用流,最终的servlet将无法读取任何数据。

避免这种情况的最佳方法是什么?我实现了HttpServletRequestWrapper here,它将流的内容读入字节数组。但是,这可能会使用大量内存来存储请求。

private HttpServletRequestWrapper getWrappedRequest(HttpServletRequest httpRequest, final byte[] reqBytes)
   throws IOException {

final ByteArrayInputStream byteInput = new ByteArrayInputStream(reqBytes);
return new HttpServletRequestWrapper(httpRequest) {

  @Override
  public ServletInputStream getInputStream() throws IOException {
    ServletInputStream sis = new ServletInputStream() {

      @Override
      public int read() throws IOException {
        return byteInput.read();
      }
    };
    return sis;
  }
};
}

有更好的方法吗?我们可以在不消耗流的情况下读取参数吗? (有些东西类似于peek)我们可以重置流吗?

1 个答案:

答案 0 :(得分:2)

如果您正在使用POST请求并从httpRequest读取参数,这将影响InputStream,您将在其他需要阅读的部分遇到问题。
这在ServletRequest#getParameter javadoc:

中有说明
  

如果参数数据是在请求体中发送的,例如发生   使用HTTP POST请求,然后通过直接读取正文   getInputStream()或getReader()可能会干扰执行   这种方法。

ServletInputStream源自InputStream并继承markSupported reset等实际上是无操作的,因此您无法重置ServletInputStream
这意味着您必须使用它。