[英]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.主要有以下三个原因。
FacesServlet
is not invoked. FacesServlet
没有被调用。FacesServlet
mapping 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 不利。
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.但理想情况下,您应该始终使用可用的最新版本。
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 中捆绑依赖项。
JSF has a very steep learning curve for those unfamiliar with basic HTTP , HTML and Servlets .对于那些不熟悉基本HTTP 、 HTML和Servlets 的人来说,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 页面开始并订购一本权威书籍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.