Использование Facelets вместо JSP-результатов в java.lang.StackOverflowError в javax.servlet.http.HttpServletRequestWrapper.getSession()

Я использую JBoss4.2 с Eclipse IDE. Когда я запускаю программу hellojsf с использованием технологии просмотра JSP, она работает нормально. Когда я пытаюсь использовать Facelets с теми же компонентами, я получаю следующее исключение:

2012-06-20 12:41:30,941 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/HelloJSF].[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
java.lang.StackOverflowError
    at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
    at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:545)
    at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
    at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:545)
    at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
    at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:545)

Как это вызвано и как я могу его решить?

Ответ 1

FacesServlet работает в бесконечном цикле. Это может произойти, если вы используете старый JSF 1.2 вместо нового JSF 2.x и не настроили JSF правильно использовать XHTML вместо JSP. JSF 1.2 не поддерживает Facelets, в то время как JSF 2.x имеет Facelets в комплекте.

Если обновление до JSF 2.0 не является вариантом (JBoss 4.2 как контейнер, совместимый с Servlet 2.5, должен его поддерживать), тогда вам нужно установить Facelets 1.x отдельно. Загрузите jsf-facelets-1.1.15.jar и оставьте его в /WEB-INF/lib и отредактируйте web.xml, чтобы сообщить JSF использовать .xhtml как суффикс по умолчанию.

<context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xhtml</param-value>
</context-param>

Шаблон URL FacesServlet должен не быть *.xhtml, это приведет к его запуску в бесконечном цикле. Просто держите его *.jsf.

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

Кроме того, не забудьте настроить обработчик вида Facelets в faces-config.xml.

<application>
    <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>    
</application> 

Теперь вы можете открывать файлы Facelets обычным способом с помощью http://localhost:8080/context/page.jsf, как и для JSP файлов, с той лишь разницей, что у вас должен быть page.xhtml файл вместо page.jsp.

При использовании JSF 2.x контекстный параметр и обработчик вида не нужны, поскольку они уже являются значениями по умолчанию для JSF 2.x. Также при использовании JSF 2.x шаблон URL можно безопасно установить на *.xhtml.

См. также: