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

Java HttpServletRequestWrapper,setReadListener/isFinished/isReady的示例实现?,java,spring,servlets,Java,Spring,Servlets,我正在尝试调整HttpServletRequestWrapper(请参阅),以便在过滤器中使用HTTP Post正文后能够读取它。现在我遇到了一个关于如何实现ServletInputStream的挑战。从规范3.1开始,必须实施新的方法 完成了 我准备好了 setReadListener 我正在寻找关于如何实现这些方法的示例或代码。有什么提示吗?您可以在spring框架中进行检查 可以找到源代码 由于Spring是带有Apache2许可证的开源软件,您可以从代码开始构建自己的版本。示例实现:

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

  • 完成了
  • 我准备好了
  • setReadListener
我正在寻找关于如何实现这些方法的示例或代码。有什么提示吗?

您可以在spring框架中进行检查

可以找到源代码


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

示例实现:

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");
        }
    }
}
import com.google.common.primitives.Bytes;
导入javax.servlet.ReadListener;
导入javax.servlet.ServletInputStream;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletRequestWrapper;
导入java.io.ByteArrayInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.util.array;
公共类AuthenticationRequestWrapper扩展了HttpServletRequestWrapper{
//标记::变量[]
私有字节[]请求体=新字节[0];
private boolean bufferFilled=false;
//end::variables[]
/**
-构造一个封装给定请求的请求对象。
*
-@param请求包装请求
-如果请求为空,@将引发IllegalArgumentException
*/
公共AuthenticationRequestWrapper(HttpServletRequest请求){
超级(请求);
}
//标记::getRequestBody[]
公共字节[]getRequestBody()引发IOException{
如果(缓冲区已填充){
返回Arrays.copyOf(requestBody,requestBody.length);
}
InputStream InputStream=super.getInputStream();
字节[]缓冲区=新字节[102400];//100kb缓冲区
int字节读取;
而((bytesRead=inputStream.read(缓冲区))!=-1){
requestBody=Bytes.concat(this.requestBody,Arrays.copyOfRange(buffer,0,bytesRead));//
}
bufferFilled=true;
返回请求主体;
}
//end::getRequestBody[]
//标记::getInputStream[]
@凌驾
公共ServletiInputStream getInputStream()引发IOException{
返回新的CustomServletInputStream(getRequestBody());//
}
//end::getInputStream[]
私有静态类CustomServletInputStream扩展了ServletInputStream{
私有ByteArrayInputStream缓冲区;
公共CustomServletInputStream(字节[]内容){
this.buffer=新的ByteArrayInputStream(内容);
}
@凌驾
public int read()引发IOException{
返回buffer.read();
}
@凌驾
公共布尔值已完成(){
返回缓冲区。可用()==0;
}
@凌驾
公共布尔值isReady(){
返回true;
}
@凌驾
公共void setReadListener(ReadListener listener){
抛出新的RuntimeException(“未实现”);
}
}
}

我不知道在哪里可以找到所需的信息。您实现了吗?没有,我一直使用MockHttpServletRequest来测试这些方法是servlet 3.1,而不是servlet 3。0@BrianClozel感谢您指出,更新了问题您实现了吗?请参阅我们如何实现的示例。获取错误“getReader()已为此请求调用了“