java HttpServletRequestWrapper,setReadListener / isFinished / isReady 的示例实现?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29208456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:52:42  来源:igfitidea点击:

HttpServletRequestWrapper, example implementation for setReadListener / isFinished / isReady?

javaspringservlets

提问by Marco

I am trying to adapt a HttpServletRequestWrapper (see How to read InputStream multiple times) to be able te read the HTTP Post body after consuming it in a filter. Now I run into a challenge on how to implement the ServletInputStream. As of spec 3.1 there are new methods that have to be implemented.

我正在尝试调整 HttpServletRequestWrapper(请参阅如何多次读取 InputStream),以便在过滤器中使用它后能够读取 HTTP Post 正文。现在我遇到了一个关于如何实现 ServletInputStream 的挑战。从规范 3.1 开始,必须实现一些新方法。

  • isFinished
  • isReady
  • setReadListener
  • 已完成
  • 准备好了
  • 设置读取监听器

I am looking for examples or some code on how these methods can be implemented. Any hints?

我正在寻找有关如何实现这些方法的示例或一些代码。任何提示?

回答by Marco

Example implementation:

示例实现:

import com.google.common.primitives.Bytes;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

public class AuthenticationRequestWrapper extends HttpServletRequestWrapper {

    // tag::variables[]
    private byte[] requestBody = new byte[0];
    private boolean bufferFilled = false;
    // end::variables[]

    /**
     - Constructs a request object wrapping the given request.
     *
     - @param request The request to wrap
     - @throws IllegalArgumentException if the request is null
     */
    public AuthenticationRequestWrapper(HttpServletRequest request) {
        super(request);
    }


    // tag::getRequestBody[]
    public byte[] getRequestBody() throws IOException {
        if (bufferFilled) {
            return Arrays.copyOf(requestBody, requestBody.length);
        }

        InputStream inputStream = super.getInputStream();

        byte[] buffer = new byte[102400]; // 100kb buffer

        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            requestBody = Bytes.concat(this.requestBody, Arrays.copyOfRange(buffer, 0, bytesRead)); // <1>
        }

        bufferFilled = true;

        return requestBody;
    }
    // end::getRequestBody[]

    // tag::getInputStream[]
    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new CustomServletInputStream(getRequestBody()); // <1>
    }
    // end::getInputStream[]

    private static class CustomServletInputStream extends ServletInputStream {

        private ByteArrayInputStream buffer;

        public CustomServletInputStream(byte[] contents) {
            this.buffer = new ByteArrayInputStream(contents);
        }

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

        @Override
        public boolean isFinished() {
            return buffer.available() == 0;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener listener) {
            throw new RuntimeException("Not implemented");
        }
    }
}

回答by Giovanni

you can check MockHttpServletRequestin the spring framework

您可以在 spring 框架中检查MockHttpServletRequest

The source code could be found here

源代码可以在这里找到

Since Spring is open source with Apache2 license you can start from the code and build your own version.

由于 Spring 是开源的 Apache2 许可证,您可以从代码开始并构建您自己的版本。