调用request.getReader()后重置HttpRequest

Noa*_*evo 13 java httprequest java-ee

有没有办法在a上调用getReader()方法HttpRequest,然后"重置"请求,以便其他调用getReader()不会抛出java.lang.IllegalStateException

bme*_*ing 12

像其他人说的那样,不,我认为没有办法重置请求.

我一直处于想要在继续​​之前在ServletFilter中记录请求内容的情况.这是一篇论坛帖子,帮助我弄清楚如何创建HttpServletRequestWrapper像Stephen C这样的人.将存储数据,所以你可以调用getReader()getInputStream()多次.

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MyRequestWrapper extends HttpServletRequestWrapper {

    private HttpServletRequest original;
    private byte[] reqBytes;
    private boolean firstTime = true;

    public MyRequestWrapper(HttpServletRequest request) {
        super(request);
        original = request;
    }

    @Override
    public BufferedReader getReader() throws IOException{

        if(firstTime)
            firstTime();

        InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(reqBytes));
        return new BufferedReader(isr);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {

        if(firstTime)
            firstTime();

        ServletInputStream sis = new ServletInputStream() {
            private int i;

            @Override
            public int read() throws IOException {
                byte b;
                if(reqBytes.length > i)
                    b = reqBytes[i++];
                else
                    b = -1;

                return b;
            }
        };

        return sis;
    }

    private void firstTime() throws IOException{
        firstTime = false;
        StringBuffer buffer = new StringBuffer();
        BufferedReader reader = original.getReader();
        String line;
        while((line = reader.readLine()) != null){
            buffer.append(line);
        }
        reqBytes = buffer.toString().getBytes();
    }
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*n C 11

简单回答是不".

该流不可重置,并且没有API方法可以让您重新打开它.(并且有充分的理由.它将要求servlet基础结构保留输入的副本,以防 servlet决定重新打开流.这将是一个无根据的开销.)

如果你想做这种事情,你需要编写代码来保存自己的数据副本.如果你在Filter(或Tomcat Valve)中实现它,那么你可以创建一个HttpServletRequestWrapper隐藏你已经读过数据的事实....正如@Vineet所建议的那样.