JSF ServletException, когда расширение файла .jsf, но как .xhtml

Как только я попытаюсь открыть свой index.xhtml через «http://localhost:8080/beginner/faces/index.jsf», я получу следующее исключение:

javax.servlet.ServletException
javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
    org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)

java.lang.NullPointerException
com.sun.faces.renderkit.RenderKitImpl.createResponseWriter(RenderKitImpl.java:228)
com.sun.faces.application.view.JspViewHandlingStrategy.renderView(JspViewHandlingStrategy.java:214)
com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
    javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
    org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)


note The full stack trace of the root cause is available in the JBoss Web/7.0.13.Final logs.

В eclipse я создал проект Maven с помощью «мастера нового проекта Maven» и выбрал идентификатор группы: «org.jboss.spec.archetypes», идентификатор артефакта «jboss-javaee6-webapp-blank-archetype» версия: 7.13 Я использую JBoss 7.1.1.FINAL и пробовал JDK 6 и JDK7

index.xthml выглядит так:

<?xml version="1.0" encoding= "UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>First JSF</title>
    </h:head>
        <h:body>
            <h1>Hello there</h1>
        </h:body>
</html>

Я часами ищу причину, но не могу найти никакого решения, даже несмотря на то, что я сделал все шаги, которые мне велел сделать этот мастер-класс.


person user3272488    schedule 04.02.2014    source источник
comment
Было бы неплохо увидеть, что находится в вашем файле web.xml? Это может быть связано с используемыми вами шаблонами сервлета и URL-адресов.   -  person Omoro    schedule 05.02.2014


Ответы (1)


Это действительно файл XHTML (Facelets)?

Посмотрите поближе на имя класса в следующей строке трассировки стека, чтобы узнать, кто обрабатывает представление:

com.sun.faces.application.view.JspViewHandlingStrategy.renderView(JspViewHandlingStrategy.java:214)

Эй, он обрабатывается как файл JSP! Что-то здесь определенно не так. Можно было бы ожидать здесь FaceletViewHandlingStrategy, если бы он действительно рассматривался как файл Facelets.

Вернемся к URL:

http://localhost:8080/beginner/faces/index.jsf

Хм? Он содержит 2 (два!) типичных FacesServlet шаблона сопоставления URL-адресов! /faces/* и *.jsf. Большая вероятность того, что это вызвало некоторую путаницу во внутреннем коде JSF, если вы действительно зарегистрировали их оба в web.xml вашего веб-приложения (как это делают многие некачественные онлайн-руководства и образцы кода). Если физический файл Facelets не может быть найден, он по умолчанию использует JSP. Если сопоставление /faces/* совпало, то JSF предположил бы, что /index.jsf является физическим файлом. Однако это явно не так. Это должно быть /index.xhtml.

Как именно вы пришли к этому URL-адресу с двойным сопоставлением? Был ли учебник, который вы читаете, действительно инструктировал вас таким образом? Разве вы не должны вместо этого использовать

http://localhost:8080/beginner/index.jsf

or

http://localhost:8080/beginner/faces/index.xhtml

?

Обратите внимание, что /faces в этом конкретном случае должен быть виртуальным URL-адресом, а не фактической папкой в ​​веб-контенте вашей структуры проекта!

В любом случае... Эти шаблоны сопоставления URL-адресов являются пережитком устаревшей эпохи JSF 1.x. Начиная с JSF 2.0, можно просто сопоставить FacesServlet с *.xhtml напрямую, не возясь с виртуальными URL-адресами.

Если можете, избавьтесь от всех остальных <servlet-mapping> и <url-pattern>, чтобы в конечном итоге получить это для FacesServlet:

<servlet>
    <servlet-name>facesServlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>facesServlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

Затем вы можете открыть страницу,

http://localhost:8080/beginner/index.xhtml

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

Смотрите также:

person BalusC    schedule 04.02.2014
comment
Как всегда отлично, +1. Один вопрос: работает ли это сопоставление FacesServlet для Facelets 1.x, работающего внутри JSF 2? - person user207421; 05.02.2014
comment
@EJP: Нет, к сожалению, нет. Это приведет к переполнению стека. - person BalusC; 05.02.2014