简体   繁体   English

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

[英]Is it possible to read HttpRequest parameters without consuming stream?

I am looking at the implementation of the HiddenMethodFilter in sitebricks here : 我期待在sitebricks的HiddenMethodFilter实施这里

At line 65 there is the following code: 在第65行,有以下代码:

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

It checks if a specific parameter was set and uses that to wrap the request. 它检查是否设置了特定参数并使用它来包装请求。 However, in reading that parameter it will consume the stream and the eventual servlet will not be able read any data. 但是,在读取该参数时,它将使用流,并且最终的servlet将无法读取任何数据。

What would be the best way to avoid this? 什么是避免这种情况的最佳方法? I implemented the HttpServletRequestWrapper here which reads the contents of the stream into a byte array. 我在这里实现了HttpServletRequestWrapper 它将流的内容读入字节数组。 This however may use a lot of memory to store the requests. 但是,这可能会使用大量内存来存储请求。

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;
  }
};
}

Is there a better way? 有没有更好的办法? can we read the parameter without consuming the stream? 我们可以在不消耗流的情况下读取参数吗? (Some thing similar to peek) can we reset the stream? (有些东西类似于peek)我们可以重置流吗?

If you are using POST requests and read parameters from the httpRequest this will affect the InputStream and you will have problems in other parts needing to read it. 如果您正在使用POST请求并从httpRequest读取参数,这将影响InputStream并且您将在需要读取它的其他部分遇到问题。
This is stated in ServletRequest#getParameter javadoc: 这在ServletRequest#getParameter javadoc中说明:

If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then reading the body directly via getInputStream() or getReader() can interfere with the execution of this method. 如果参数数据是在请求正文中发送的,例如在HTTP POST请求中发生,则直接通过getInputStream()或getReader()读取正文可能会干扰此方法的执行。

The ServletInputStream is derived from InputStream and inherits the markSupported reset etc which are actually no-ops and so you can not reset a ServletInputStream . ServletInputStream派生自InputStream并继承了markSupported reset等,它们实际上是无操作,因此您无法重置ServletInputStream
This means that you will have to consume it. 这意味着您必须使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM