有三个主要原因。
FacesServlet
不被调用。
- XML 命名空间 URI 丢失或错误。
- 已加载多个 JSF 实现。
1. 确保 URL 匹配FacesServlet
映射
链接的 URL(您在浏览器地址栏中看到的 URL)必须与定义的 相匹配<url-pattern>
,FacesServlet
以便web.xml
让所有 JSF 工作运行。它FacesServlet
负责解析 XHTML 文件、收集提交的表单值、执行转换/验证、更新模型、调用操作和生成 HTML 输出。如果您不调用FacesServlet
by URL,那么您将得到的(通过右键单击查看,在浏览器中查看源代码)确实是原始 XHTML 源代码。
<url-pattern>
例如,如果是*.jsf
,则链接应该指向/register.jsf
而不是/register.xhtml
。如果它是例如/faces/*
,就像你有,那么链接应该指向/faces/register.xhtml
而不是/register.xhtml
。避免这种混淆的一种方法是将<url-pattern>
from更改/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
,那么您可能还希望阻止最终用户通过 URL 直接访问 XHTML 源代码文件。在这种情况下,您可以<security-constraint>
在<url-pattern>
of上添加*.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>
2017 年 4 月推出的 JSF 2.3 已经通过在 webapp 启动期间自动注册FacesServlet
URL 模式来解决上述所有问题。*.xhtml
因此,另一种选择是简单地升级到最新的可用 JSF 版本,它应该是 JSF 2.3 或更高版本。但理想情况下,您仍应显式注册FacesServlet
仅一个 URL 模式,*.xhtml
因为对于完全相同的资源(如/register.xhtml
、/register.jsf
、 )/register.faces
有多个可能的 URL/faces/register.xhtml
对 SEO 不利。
也可以看看:
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实现
另一个可能的原因是您的 web 应用程序加载了多个 JSF 实现,相互冲突和破坏。例如,当您的 webapp 的运行时类路径被多个不同版本的 JSF 库污染时,或者在特定的 Mojarra 2.x + Tomcat 8.x 组合中,当ConfigureListener
webapp 中有不必要的条目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 时,请绝对确保以正确的方式声明依赖项并了解依赖项范围。重要的是,当目标服务器已经提供了依赖项时,不要在 webapp 中捆绑依赖项。
也可以看看:
确保您以正确的方式学习 JSF
对于不熟悉基本HTTP、HTML和Servlet的人来说,JSF 的学习曲线非常陡峭。互联网上有很多低质量的资源。请忽略由业余爱好者维护的代码片段抓取网站,这些网站主要关注广告收入而不是教学,例如 roseindia、tutorialspoint、javabeat、baeldung 等。它们很容易被干扰的广告链接/横幅识别。也请忽略处理侏罗纪 JSF 1.x 的资源。它们很容易通过使用 JSP 文件而不是 XHTML 文件来识别。JSP 作为视图技术自 2009 年的 JSF 2.0 以来已被弃用。
要以正确的方式开始,请从我们的 JSF wiki 页面开始并订购一本权威书籍。
也可以看看: