Скрыть JSP из FacesContext

#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-адрес моей страницы был:

http://localhost:8080/myappname/Error.jsp

Но это доступно только:

http://localhost:8080/myappname/faces/Error.jsp

То же самое происходит, когда я объявляю 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-адресе, чтобы этот запрос не проходил через фильтр.