Настройка имени вида в весеннем фильтре - PullRequest
9 голосов
/ 01 сентября 2010

У меня есть ErrorFilter, который расширяет пружину GenericFilterBean.Я хочу показать страницу ошибки, украшенную плитками, если произойдет какая-либо ошибка.

Есть ли способ установить имя вида из фильтра?

<filter>
    <filter-name>errorFilter</filter-name>
    <filter-class>com.abc.filter.ErrorFilter</filter-class>
    <init-param>
        <param-name>errorPage</param-name>
        <param-value>/jsp/errorpage.jsp</param-value>
    </init-param>
</filter>

Это конфигурация в web.xml иdoFilter метод в errorfilter выглядит следующим образом:

public void doFilter(ServletRequest req, ServletResponse resp,
        FilterChain chain) throws IOException, ServletException {

    HttpServletRequest httpReq = (HttpServletRequest) req;
    StringBuffer reqUrl = httpReq.getRequestURL();
    try {
        chain.doFilter(req, resp);
    } catch (Exception ex) {
        String requestRepresentation = createRequestRepresentation(req);
        errorService.handleException(reqUrl.toString(), ex, requestRepresentation);
        req.getRequestDispatcher(
                getFilterConfig().getInitParameter("errorPage")).forward(req, resp);
    } catch (Error er) {
        errorService.handleError(reqUrl.toString(), er);
        req.getRequestDispatcher(
                getFilterConfig().getInitParameter("errorPage")).forward(req, resp);
    }
}

Текущая страница ошибки не украшена тайлами, поэтому я хочу украсить ее обычным верхним и нижним колонтитулом и вызвать егопросмотреть имя из фильтра.

Возможно ли это?

Редактировать: По сути, мы хотим иметь возможность сделать что-то похожее на метод контроллера, т.е. return "имя представления ";

Уже пробовал:

  • httpResponse.sendRedirect (" errorPageView "); не работает, он перенаправляет на http://server/fooerrorPageView
  • request.getRequestDispatcher ("errorPageView"). Forward (запрос, ответ); также нет, как и выше (без перенаправления http, но выдает то же самое "без такой ошибки страницы«содержание»

Ответы [ 5 ]

1 голос
/ 18 июня 2015

Фильтр приходит до весны.Spring bean-компоненты могут быть внедрены в Filter с использованием механизма ApplicationContextAware, но формирование Spring MVC-представления означает, что вам придется использовать всю инфраструктуру Spring MVC в вашем Filter.Я думаю, что это невозможно, и вам придется пересылать запрос с помощью RequestDispatcher не в весеннее представление, а в собственное пользовательское представление.

1 голос
/ 18 мая 2015

я думаю, что это невозможно, потому что это фильтр сервлетов, который будет применяться после применения сервлета Mapper. в общем, сервлет отображения запросов считает, что он завершен, и передает запрос обратно в контейнер сервлета.

просмотр имен работает только ВНУТРИ весны - вне весны, в контейнере сервлета вам придется говорить об URL, а не просматривать имена.

перенаправление на конкретный URL будет работать. для этого вы должны знать о различиях между перенаправлением и переадресацией.

редирект отправляет клиенту следующий заголовок:

Расположение: http://server/new/location

вместе с кодом состояния 301 (постоянное перенаправление, чтобы сообщить клиенту, что он может кэшировать эту информацию) или 307 (временное перенаправление, чтобы сообщить клиенту, что он должен запросить снова в следующий раз, потому что перенаправление может измениться)

Переадресация на диспетчере запросов в основном имитирует новый запрос, и вы можете отправить запрос ЛЮБОМУ сервлету в том же контейнере. это означает, что вы должны ТАКЖЕ учитывать контекстный путь, то есть ответ, который @iimuhin дал:

    response.sendRedirect(
         request.getContextPath() + 
         getFilterConfig().getInitParameter("errorPage"));

на самом деле правильный путь. Вы можете (должны) добавить протоколирование, чтобы увидеть, что на самом деле происходит и какие пути на самом деле используются.

также - вы должны знать о буферизации. ответ сервлета обычно буферизируется, и клиенту ничего не отправляется, пока не будет заполнен буфер или не завершится вся обработка.

когда он очищен, заголовки записываются первыми. это означает, что изменение заголовков ПОСЛЕ того, как ответ был сброшен, невозможно, поскольку они уже отправлены.

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

в вашем случае вы можете увеличить размер буфера в ответе:

    response.setBufferSize(int size) 

перед вызовом chain.doFilter (), чтобы избежать преждевременного сброса.

1 голос
/ 20 мая 2015

Почему вы не используете механизм обработки ошибок Spring?вот хороший пост об этом (с примерами) - https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

Кроме этого, не уверен, существует ли чистый способ сделать это.Другие предложения могут заключаться в обращении к вашему приложению, чтобы получить ответ страницы с ошибкой и заменить вывод ответа этим (в этом случае вам также потребуется использовать «буферизованный» ответ http, чтобы убедиться, что поток еще не очищен) или сделатьперенаправить на ошибку URL.

0 голосов
/ 28 сентября 2015

Просто проверьте ваш URL перенаправления. Вы можете получить доступ к странице с помощью URL.

public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url)
        throws IOException {
    String redirectUrl = request.getContextPath() + url;
    redirectUrl = response.encodeRedirectURL(redirectUrl);

    if (logger.isDebugEnabled()) {
        logger.debug("Redirecting to '" + redirectUrl + "'");
    }

    response.sendRedirect(redirectUrl);
}
0 голосов
/ 05 сентября 2010

Должен быть способ сделать это с Spring MVC, но я полагаю, что перенаправления достаточно.

try {
    chain.doFilter(req, resp);
} catch (Exception ex) {
    if (response.isCommitted()) {
        log(ex); // at least a part of the response is already sent to the client, you can't do much about it
    } else {
        session.setAttribute("last.exception", ex);
        response.sendRedirect(request.getContextPath() + getFilterConfig().getInitParameter("errorPage"));
    }
}

P.S. не поймай ошибку!

...