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

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

Веб-контент
 |- index.xhtml
 |- register.xhtml
 |- шаблоны
 |    |--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 ответ

Решение

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

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

1. Убедитесь, что URL совпадает FacesServlet отображение

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, когда есть ненужные ConfigureListener запись в веб-приложении web.xml заставляя это быть загруженным дважды.

<!-- 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 и закажите авторитетную книгу.

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

Другие вопросы по тегам