JSF возвращает пустую / непарсированную страницу с простым / необработанным исходным кодом XHTML / XML / EL вместо отрисованного вывода HTML - PullRequest
16 голосов
/ 24 июня 2010

У меня есть несколько файлов Facelets, как показано ниже.

WebContent
 |-- index.xhtml
 |-- register.xhtml
 |-- templates
 |    |--userForm.xhtml
 |    `--banner.xhtml
 :

Обе страницы используют шаблоны из каталога /templates. Мой /index.xhtml нормально открывается в браузере. Я получаю сгенерированный вывод HTML. У меня есть ссылка в файле /index.xhtml на файл /register.xhtml. Однако мой /register.xhtml не анализируется и возвращается в виде простого XHTML / raw XML вместо сгенерированного HTML-вывода. Когда я щелкаю правой кнопкой мыши страницу в браузере и выполняю Просмотр исходного кода , я все равно вижу исходный код XHTML вместо сгенерированного вывода HTML. Похоже, что шаблон не применяется.

Однако, когда я открываю /register.xhtml как /faces/register.xhtml в адресной строке браузера, он отображается правильно. Как это вызвано и как я могу решить это?

1 Ответ

42 голосов
/ 25 июня 2010

Есть три основных причины.

  1. FacesServlet не вызывается.
  2. URI пространства имен XML отсутствуют или неверны.
  3. Загружено несколько реализаций JSF.

1. Убедитесь, что URL соответствует FacesServlet mapping

URL-адрес ссылки (URL, который вы видите в адресной строке браузера) должен соответствовать <url-pattern> из FacesServlet, как определено в web.xml, чтобы запустить все работы JSF. FacesServlet отвечает за синтаксический анализ файла XHTML, сбор отправленных значений форм, выполнение преобразования / проверки, обновление моделей, запуск действий и генерацию вывода HTML. Если вы не вызовете FacesServlet по URL-адресу, то все, что вы получите (и увидите с помощью правого клика, Просмотр исходного кода в браузере), действительно является исходным кодом XHTML.

Если <url-pattern>, например, *.jsf, то ссылка должна указывать на /register.jsf, а не /register.xhtml. Если это, например, /faces/*, как у вас, то ссылка должна указывать на /faces/register.xhtml, а не /register.xhtml. Один из способов избежать этой путаницы - просто изменить <url-pattern> с /faces/* на *.xhtml. Таким образом, ниже приведено идеальное отображение:

<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>

Если по какой-то причине вы не можете изменить <url-pattern> на *.xhtml, то, вероятно, вы также хотели бы запретить конечным пользователям прямой доступ к файлам исходного кода XHTML по URL-адресу. В этом случае вы можете добавить <security-constraint> к <url-pattern> из *.xhtml с пустым <auth-constraint> в web.xml, что предотвращает это:

<security-constraint>
    <display-name>Restrict direct access to XHTML files</display-name>
    <web-resource-collection>
        <web-resource-name>XHTML files</web-resource-name>
        <url-pattern>*.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint />
</security-constraint> 

Предстоящий JSF 2.3 решит все вышеперечисленное, автоматически зарегистрировав FacesServlet для шаблона URL *.xhtml во время запуска веб-приложения.

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


2. Убедитесь, что пространства имен XML соответствуют версии JSF

С момента появления JSF 2.2 другой вероятной причиной является то, что пространства имен XML не соответствуют версии JSF. xmlns.jcp.org, как показано ниже, является новым с JSF 2.2 и не работает в более старых версиях JSF. Симптомы почти такие же, как если бы FacesServlet не вызывалось.

<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

Если вы не можете перейти на JSF 2.2, вам нужно вместо этого использовать старые java.sun.com пространства имен XML:

<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">

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


3. Загружено несколько реализаций JSF

Еще одна вероятная причина заключается в том, что ваше веб-приложение загружает несколько реализаций JSF, конфликтующих и портящих друг друга. Например, когда путь к классам во время выполнения вашего веб-приложения загрязнен несколькими различными версиями библиотек JSF или в определенной комбинации Mojarra 2.x + Tomcat 8.x, когда в web.xml веб-приложения есть ненужная запись ConfigureListener, вызывающая его загрузку в два раза.

<!-- You MUST remove this one from web.xml! -->
<!-- This is actually a workaround for buggy GlassFish3 and Jetty servers. -->
<!-- When leaving this in and you're targeting Tomcat, you'll run into trouble. -->
<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

При использовании Maven убедитесь, что вы правильно объявляете зависимости и понимаете области действия зависимостей. Важно отметить, что не связывайте зависимости в веб-приложении, если они уже предоставлены целевым сервером.

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


Убедитесь, что вы изучаете JSF правильно

У JSF очень крутая кривая обучения для тех, кто не знаком с основными HTTP , HTML и Сервлетами .В Интернете много некачественных ресурсов.Не обращайте внимания на сайты с фрагментами кода, поддерживаемые любителями, уделяющими основное внимание доходам от рекламы, а не обучению, таким как roseindia, tutorialspoint, javabeat и т. Д. Их легко узнать по нарушению рекламных ссылок / баннеров.Также, пожалуйста, не обращайте внимания на ресурсы, связанные с юрским JSF 1.x.Их легко узнать, используя файлы JSP вместо файлов XHTML.JSP как технология представления уже устарела, начиная с JSF 2.0 в 2009 году.

Чтобы начать работу правильно, начните с нашей вики-страницы JSF и закажите авторитетную книгу .

См. Также:

...