5

我在这里查看sitebricks 中 HiddenMethodFilter 的实现:

在第 65 行有以下代码:

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

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

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

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 的东西)我们可以重置流吗?

4

1 回答 1

2

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

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

ServletInputStream派生自InputStream并继承了实际上是无操作的markSupported resetetc,因此您无法重置ServletInputStream.
这意味着你将不得不消费它。

于 2012-04-26T16:40:53.773 回答