【问题标题】:Is it possible to read HttpRequest parameters without consuming stream?是否可以在不消耗流的情况下读取 HttpRequest 参数?
【发布时间】:2012-05-07 09:42:00
【问题描述】:

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

【问题讨论】:

    标签: java servlets servlet-filters


    【解决方案1】:

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

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

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

    【讨论】:

    • 是否有其他方法可以将元数据从网页获取到不需要数据位于请求正文中的 servlet 容器?
    • 使用 GET 而不是 POST。或者为特定的功能需求寻找替代方法,这样您就不需要多次阅读正文。
    • @UsmanIsmail: 读取一次输入流,缓冲它并将其传递给需要读取它的各种组件
    • @Jim 已经在那里只是想知道是否有更好的解决方案不需要缓冲可能非常大的数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 2012-06-27
    相关资源
    最近更新 更多