Можно ли перенаправить или перенаправить фильтр сервлета после подтверждения ответа? - PullRequest
7 голосов
/ 04 августа 2010

Логика в том, что фильтр получает удар, условие не выполняется, поэтому он проходит через цепочку фильтров. После подтверждения ответа фильтр срабатывает, и условие теперь выполняется (атрибут запроса был установлен). Он входит, чтобы выполнить пересылку, но страница никогда не переходит. Я знаю, что это как-то связано с фиксацией ответа, потому что я тестировал другую логику, в которой он пересылается, прежде чем он попадает в цепочку в первый раз, и он успешно пересылает.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

    HttpServletRequest httpServletRequest = (HttpServletRequest)request;

    if (some condition equals true) {
        httpServletRequest.getRequestDispatcher("/home.jsp").forward(request, response);
        return;
    } else {
        chain.doFilter(request, response);
    }
}

Пример из моего дескриптора развертывания:

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.filters.MyFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
    <dispatcher>REQUEST</dispatcher>  
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping>

Ответы [ 2 ]

16 голосов
/ 04 августа 2010

Статус «принят» для HttpServletResponse - это действительно способ узнать, были ли заголовки ответа записаны в базовый сокет. В «совершенном» ответе была написана (по крайней мере) первая строка. Поскольку в первой строке ответа содержится код состояния, из этого следует, что вы не можете изменить код состояния подтвержденного ответа ... и это означает, что уже слишком поздно менять статус на 3xx, чтобы выполнить перенаправление. Точно так же вы не можете выполнить локальную пересылку, потому что вы уже начали отправлять ответ.

5 голосов
/ 14 декабря 2011

Вы можете достичь желаемого с помощью пользовательского HttpServletResponse . Вы передаете этот упакованный HttpServletResponse по цепочке фильтров. Вы можете предоставить локальный OutputStream, в котором хранятся все запросы на запись, локальные переменные для хранения кода состояния и заголовки. Вернувшись в свой фильтр, вы можете решить выполнить перенаправление или скопировать обратно результаты из локальных переменных из оболочки в исходный ServletResponse (т.е. установить код состояния и заголовок и скопировать результаты из локального потока вывода в поток вывода ответа сервлета).

Edit:

Обратитесь к разделу Программирование пользовательских запросов и ответов для примера кода, который использует CharResponseWrapper. В примере используется пользовательский Writer, но его можно легко расширить до OutputStream. В зависимости от того, как используется ваш сервлет, вам нужно переопределить один или оба из getWriter() и getOutputStream(), чтобы отложить принятие чего-либо в исходном ответе. Кроме того, вам нужно переопределить isCommitted(), чтобы вернуть false, чтобы форвард мог быть выполнен в любое время по цепочке фильтров. Вам также потребуется переопределить resetBuffer() для инициализации нового OutputStream / Writer для хранения нового содержимого (включая заголовки) после перенаправления / пересылки.

...