简体   繁体   English

JSF 返回带有普通/原始 XHTML/XML/EL 源而不是呈现的 HTML 输出的空白/未解析页面

[英]JSF returns blank/unparsed page with plain/raw XHTML/XML/EL source instead of rendered HTML output

I have some Facelets files like below.我有一些如下所示的 Facelets 文件。

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

Both pages are using templates from /templates directory.两个页面都使用/templates目录中的/templates My /index.xhtml opens fine in browser.我的/index.xhtml在浏览器中打开正常。 I get the generated HTML output.我得到生成的 HTML 输出。 I have a link in /index.xhtml file to /register.xhtml file.我在/index.xhtml文件中有一个指向/register.xhtml文件的链接。

However, my /register.xhtml is not getting parsed and returns as plain XHTML / raw XML instead of its generated HTML output.但是,我的/register.xhtml没有被解析并返回为纯 XHTML/原始 XML,而不是其生成的 HTML 输出。 All EL expressions in form of #{...} are displayed as-is instead of that their results are being printed. #{...}形式的所有 EL 表达式都按原样显示,而不是打印它们的结果。 When I rightclick page in browser and do View page source , then I still see the original XHTML source code instead of the generated HTML output.当我在浏览器中右键单击页面并执行View page source 时,我仍然看到原始的 XHTML 源代码而不是生成的 HTML 输出。 For example, the <h:body> did not become a <body> .例如, <h:body>没有变成<body> It looks like that the template is not being executed.看起来模板没有被执行。

However, when I open the /register.xhtml like /faces/register.xhtml in browser's address bar, then it displays correctly.但是,当我在浏览器的地址栏中打开像/faces/register.xhtml这样的/register.xhtml时,它会正确显示。 How is this caused and how can I solve it?这是怎么引起的,我该如何解决?

There are three main causes.主要有以下三个原因。

  1. FacesServlet is not invoked. FacesServlet没有被调用。
  2. XML namespace URIs are missing or wrong. XML 命名空间 URI 丢失或错误。
  3. Multiple JSF implemenations have been loaded.已加载多个 JSF 实现。

1. Make sure that URL matches FacesServlet mapping 1. 确保 URL 匹配FacesServlet映射

The URL of the link (the URL as you see in browser's address bar) has to match the <url-pattern> of the FacesServlet as definied in web.xml in order to get all the JSF works to run.链接的 URL(您在浏览器地址栏中看到的 URL)必须与web.xml中定义的FacesServlet<url-pattern>匹配,以便让所有 JSF 工作运行。 The FacesServlet is the one responsible for parsing the XHTML file, collecting submitted form values, performing conversion/validation, updating models, invoking actions and generating HTML output. FacesServlet负责解析 XHTML 文件、收集提交的表单值、执行转换/验证、更新模型、调用操作和生成 HTML 输出。 If you don't invoke the FacesServlet by URL, then all you would get (and see via rightclick, View Source in browser) is indeed the raw XHTML source code.如果您不通过 URL 调用FacesServlet ,那么您将获得的(通过右键单击查看,在浏览器中查看源代码)确实是原始 XHTML 源代码。

If the <url-pattern> is for example *.jsf , then the link should point to /register.jsf and not /register.xhtml .如果<url-pattern>是例如*.jsf ,那么链接应该指向/register.jsf而不是/register.xhtml If it's for example /faces/* , like you have, then the link should point to /faces/register.xhtml and not /register.xhtml .如果它是例如/faces/* ,就像你一样,那么链接应该指向/faces/register.xhtml而不是/register.xhtml One way to avoid this confusion is to just change the <url-pattern> from /faces/* to *.xhtml .避免这种混淆的一种方法是将<url-pattern>/faces/*更改为*.xhtml The below is thus the ideal mapping:因此,以下是理想的映射:

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

If you can't change the <url-pattern> to *.xhtml for some reason, then you probably would also like to prevent endusers from directly accessing XHTML source code files by URL.如果由于某种原因您不能将<url-pattern>更改为*.xhtml ,那么您可能还想阻止最终用户通过 URL 直接访问 XHTML 源代码文件。 In that case you can add a <security-constraint> on the <url-pattern> of *.xhtml with an empty <auth-constraint> in web.xml which prevents that:在这种情况下,您可以在*.xhtml<url-pattern> <security-constraint>上添加一个<security-constraint>并在web.xml添加一个空的<auth-constraint>以防止:

<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 which was introduced April 2017 has already solved all of above by automatically registering the FacesServlet on an URL pattern of *.xhtml during webapp's startup. 2017 年 4 月推出的 JSF 2.3 通过在 webapp 启动期间自动在*.xhtml的 URL 模式上注册FacesServlet已经解决了上述所有问题。 The alternative is thus to simply upgrade to latest available JSF version which should be JSF 2.3 or higher.因此,替代方法是简单地升级到最新的可用 JSF 版本,该版本应该是 JSF 2.3 或更高版本。 But ideally you should still explicitly register the FacesServlet on only one URL pattern of *.xhtml because having multiple possible URLs for exactly the same resource like /register.xhtml , /register.jsf , /register.faces and /faces/register.xhtml is bad for SEO.但理想情况下,您仍然应该仅在*.xhtml一种 URL 模式上显式注册FacesServlet ,因为对于完全相同的资源(如/register.xhtml/register.jsf/register.faces/faces/register.xhtml有多个可能的 URL对 SEO 不利。

See also:也可以看看:


2. Make sure that XML namespaces match JSF version 2. 确保 XML 命名空间匹配 JSF 版本

Since introduction of JSF 2.2, another probable cause is that XML namespaces don't match the JSF version.自从引入 JSF 2.2 以来,另一个可能的原因是 XML 名称空间与 JSF 版本不匹配。 The xmlns.jcp.org like below is new since JSF 2.2 and does not work in older JSF versions.如下所示的xmlns.jcp.org是自 JSF 2.2 以来的新内容,并且不适用于较旧的 JSF 版本。 The symptoms are almost the same as if the FacesServlet is not invoked.症状几乎与未调用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">

If you can't upgrade to JSF 2.2 or higher, then you need to use the old java.sun.com XML namespaces instead:如果您无法升级到 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">

But ideally you should always use the latest version where available.但理想情况下,您应该始终使用可用的最新版本。

See also:也可以看看:


3. Multiple JSF implementations have been loaded 3. 加载了多个 JSF 实现

One more probable cause is that multiple JSF implementations have been loaded by your webapp, conflicting and corrupting each other.另一个可能的原因是您的 web 应用程序加载了多个 JSF 实现,相互冲突和损坏。 For example, when your webapp's runtime classpath is polluted with multiple different versioned JSF libraries, or in the specific Mojarra 2.x + Tomcat 8.x combination, when there's an unnecessary ConfigureListener entry in webapp's web.xml causing it to be loaded twice.例如,当您的 webapp 的运行时类路径被多个不同版本的 JSF 库污染时,或者在特定的 Mojarra 2.x + Tomcat 8.x 组合中,当 webapp 的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>

When using Maven, make absolutely sure that you declare the dependencies the right way and that you understand dependency scopes.使用 Maven 时,请务必确保以正确的方式声明依赖项并了解依赖项范围。 Importantingly, do not bundle dependencies in webapp when those are already provided by the target server.重要的是,当目标服务器已经提供依赖项时,不要在 webapp 中捆绑依赖项。

See also:也可以看看:


Make sure that you learn JSF the right way确保您以正确的方式学习 JSF

JSF has a very steep learning curve for those unfamiliar with basic HTTP , HTML and Servlets .对于那些不熟悉基本HTTPHTMLServlets 的人来说,JSF 的学习曲线非常陡峭。 There are a lot of low quality resources on the Internet.互联网上有很多低质量的资源。 Please ignore code snippet scraping sites maintained by amateurs with primary focus on advertisement income instead of on teaching, such as roseindia, tutorialspoint, javabeat, baeldung, etc. They are easily recognizable by disturbing advertising links/banners.请忽略由业余爱好者维护的主要关注广告收入而不是教学的代码片段抓取网站,例如 roseindia、tutorialspoint、javabeat、baeldung 等。它们很容易通过干扰广告链接/横幅识别。 Also please ignore resources dealing with jurassic JSF 1.x.另外请忽略处理侏罗纪 JSF 1.x 的资源。 They are easily recognizable by using JSP files instead of XHTML files.通过使用 JSP 文件而不是 XHTML 文件,它们很容易识别。 JSP as view technology was deprecated since JSF 2.0 at 2009 already.自 2009 年的 JSF 2.0 以来,JSP 作为视图技术已被弃用。

To get started the right way, start at our JSF wiki page and order an authoritative book .要以正确的方式开始,请从我们的 JSF wiki 页面开始并订购一本权威书籍

See also:也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM