сброс HttpRequest после вызова request.getReader () - PullRequest
13 голосов
/ 12 июня 2011

Есть ли способ вызвать метод getReader() для HttpRequest и затем "сбросить" запрос, чтобы другие вызовы getReader() не выдавали java.lang.IllegalStateException?

Ответы [ 2 ]

12 голосов
/ 12 июня 2011

Как и другие люди говорили: нет, я не думаю, что есть способ сбросить запрос.

У меня была такая же ситуация, когда я хотел записать содержимое запроса в ServletFilter, прежде чем двигаться дальше. Вот сообщение на форуме , которое помогло мне понять, как создать HttpServletRequestWrapper, о котором говорил Стивен С. Это будет хранить данные, так что вы можете звонить 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();
    }
}
11 голосов
/ 12 июня 2011

Простой ответ - «Нет».

Поток не сбрасывается, и нет метода API, который бы позволил вам снова открыть его.(И на то есть веская причина. Требуется, чтобы инфраструктура сервлета сохраняла копию ввода на случай, если сервлет решит снова открыть поток. Это будет неоправданным расходом.)Если вы хотите делать такие вещи, вам нужно будет написать свой код, чтобы сохранить собственную копию данных.Если вы реализуете это в фильтре (или в Tomcat Valve), тогда вы можете создать HttpServletRequestWrapper, чтобы скрыть тот факт, что вы уже прочитали данные .... как предложено @ Vineet.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...