#java #jsf #servlet-filters
#java #jsf #сервлет-фильтры
Вопрос:
У меня есть приложение JSF с сервлетом Filter
, настроенным для urlPattern of /faces/*
. Я хочу скрыть JSP из контекста faces, чтобы он не проходил через сервлет Filter
. Поэтому я сохранил его в WebContent
папке моего проекта как WebContent/Error.jsp
и объявил следующим образом в web.xml
:
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/Error.jsp</location>
</error-page>
Но мой Error.jsp
никогда не подбирается. Вместо этого я вижу ошибку 404 Page not found.
Чтобы быть более понятным, я хочу Error.jsp
, чтобы URL-адрес моей страницы был:
Но это доступно только:
То же самое происходит, когда я объявляю any view-id
в faces-config.xml
. Где мне сохранить ошибку JSP, если я хочу скрыть ее из faces
контекста?
Комментарии:
1. Я не понимаю роли этого фильтра. Что он делает? Он также отображается в
ERROR
dispatcher?2. @BalusC-Спасибо за ответ. В моем фильтре я ищу атрибут в сеансе. Но в Error.jsp такого атрибута не существует. Поэтому я хочу обойти Error.jsp из filter. Это мое требование. Я не знаю, что такое диспетчер ОШИБОК. Пожалуйста, объясните.
3. @BalusC-я понял, что такое диспетчер ошибок. Мой
Error.jsp
не должен проходить черезfilter
. Где я должен разместитьError.jsp
, чтобы я мог удалитьfaces
из URL?4. Просто добавить
if
проверку в фильтр? Вы открываете его напрямую или целенаправленно создаете NPE? Если фильтр не сопоставлен сERROR
dispatcher и вы отправляете NPE по обычному запросу JSF, тогда он вообще не должен вызывать фильтр. Отсюда и запутанный характер вашего вопроса и моих вопросов в предыдущих комментариях.5. Мой фильтр не отображается в
ERROR
dispatcher, и мое приложение выдает NPE только по обычному запросу. Но мой Error.jsp не обнаруживается, когда я получаю NPE. Вместо этого он показывает трассировку стека tomcat по умолчанию.
Ответ №1:
Основываясь на приведенной до сих пор информации, похоже, что она должна работать нормально. У вас нет a <dispatcher>ERROR</dispatcher>
в фильтре, поэтому фильтр вообще не должен вызываться всякий раз, когда создается NPE.
По-видимому, NPE попал в другое исключение, потому что оно было выброшено в нелогичном месте, таком как конструктор компонента, вместо обычного метода действия компонента. В таком случае JSF перестроит его как ManagedBeanCreationException
. Контейнер получит его вместо NPE и, следовательно, не сможет найти страницу с ошибкой. На странице ошибок HTTP 500 контейнера по умолчанию вы должны прочитать самое верхнее исключение трассировки стека, чтобы определить правильное исключение для определения страницы ошибки.
Пожалуйста, имейте в виду, что исключения во время выполнения, такие как NPE, являются ошибками разработчика (ошибками!), А не производственными ошибками, и что они должны быть исправлены как можно скорее. Я бы лично просто использовал глобальную страницу ошибок HTTP 500 для такого рода ошибок:
<error-page>
<status-code>500<status-code>
<location>/errors/generic.jsp</location>
</error-page>
Для более конкретных, реальных производственных исключений вы всегда можете объявить более конкретную страницу ошибок:
<error-page>
<exception-type>com.example.YourDatabaseAccessException</exception-type>
<location>/errors/database.jsp</location>
</error-page>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/errors/sessionexpired.jsp</location>
</error-page>
Комментарии:
1. Спасибо за подробное объяснение. еще один вопрос 🙂 у меня есть еще одна страница,
Logout.jsp
которую я показываю после успешного выхода из системы. Где я могу разместить это, чтобы обойти фильтр?2. Либо просто поместите его в место, которое не соответствует
<url-pattern>
Filter
, либо (еслиFilter
у вас слишком усердный/*
шаблон), затем добавьте дополнительнуюif
проверку вdoFilter()
метод, который должен приводить к простому вызовуchain.doFilter(request, response)
всякий раз, когда запрашивается URI/contextname/Logout.jsp
.3. Мой URL-шаблон
/faces/*
. И вfaces-config.xml
. у меня есть/Logout.jsp
. Но URL дляLogout.jsp
становитсяhttp://localhost:8080/myappname/faces/Logout.jsp
. куда я могу поместить этоLogout.jsp
, чтобы избежать этогоfaces
в URL. теперь у меня этоWebContent
есть.4. Если это чистая страница JSP (почему не JSF?), Просто вызовите ее без
/faces
URL. Т.е. вызовите ее с помощью обычного<a>
элемента или обычного<form>
элемента вместо a<h:outputLink>
,<h:commandLink>
и<h:form>
. Или, если это страница JSF, просто добавьте этуif
проверку в фильтр. Однако более обычной практикой является сопоставление фильтра аутентификации с более конкретным шаблоном URL, таким как/faces/app/*
,/faces/private/*
,/faces/secured/*
, и т. Д., И помещать все ограниченные ресурсы именно в эту/app
/private
папку или/secured
папку.
Ответ №2:
Если вы определите фильтр и очистите его в своем web.xml , весь запрос будет проходить через этот фильтр, если только вы не определите сопоставление фильтров.
Я думаю, вы можете определить сопоставление фильтров в своем web.xml следующим образом:
<filter>
<filter-name>URLFilter</filter-name>
<filter-class>the filter class in your source code</filter-class>
</filter>
<filter-mapping>
<filter-name>URLFilter</filter-name>
<url-pattern>/some pages</url-pattern>//skip error.jsp here
</filter-mapping>
это не проверено, а просто вдохновение.
редактировать: вы можете узнать больше на сайте Oracle
Ответ №3:
Для меня не похоже, что фильтр Faces имеет какое-либо отношение к этой проблеме. Можете ли вы достичь http://localhost:8080/myappname/Error.jsp с полностью отключенным фильтром? Если нет, то, возможно, есть какая-то проблема с самим файлом Error.jsp?
Трудно сказать, не видя самого кода.
Комментарии:
1. @jsight- Спасибо за ответ. Как вы видите, приведенное выше объявление errorpage в
web.xml
, я дал/Error.jsp
. Ноhttp://localhost:8080/myappname/faces
добавляется спереди, и URL становитсяhttp://localhost:8080/myappname/faces/Error.jsp
. Я ищу способ избежать лиц в приведенном выше URL-адресе, чтобы этот запрос не проходил через фильтр.