我有一些如下的Facelets文件。
网页内容 |-index.xhtml |-register.xhtml |-模板 | | --userForm.xhtml | `--banner.xhtml :
两个页面都使用/templates目录中的模板。我的/index.xhtml浏览器打开正常。我得到了生成的HTML输出。我在/index.xhtml文件中有一个链接/register.xhtml。
/templates
/index.xhtml
/register.xhtml
但是,我/register.xhtml没有得到解析,而是以纯XHTML /原始XML而不是其生成的HTML输出形式返回。所有EL表达式的形式#{...}均按原样显示,而不是打印其结果。当我在浏览器中右键单击页面并执行 View page source时 ,我仍然看到原始的XHTML源代码,而不是生成的HTML输出。例如,<h:body>并没有成为<body>。看起来模板没有被执行。
#{...}
<h:body>
<body>
但是,当我在浏览器的地址栏中打开/register.xhtmllike /faces/register.xhtml时,它会正确显示。这是怎么引起的,我该如何解决?
/faces/register.xhtml
有三个主要原因。
FacesServlet
链接(如你在浏览器的地址栏中显示的网址)的网址必须匹配<url- pattern>的FacesServlet为definied中web.xml,以获得所有的JSF工作运行。的FacesServlet是一个负责解析XHTML文件,收集提交表单值,进行变换/验证,更新模型,调用操作和产生HTML输出。如果不FacesServlet通过URL 调用,那么您将获得的所有内容(并通过右键单击 查看, 在浏览器中 查看源代码 )确实是原始XHTML源代码。
<url- pattern>
web.xml
<url- pattern>例如*.jsf,如果,则链接应指向/register.jsf而不是/register.xhtml。例如/faces/*,如果像您一样,则链接应指向/faces/register.xhtml而不是/register.xhtml。避免这种混乱的一种方法是将<url- pattern>from 更改/faces/*为*.xhtml。因此,以下是理想的映射:
*.jsf
/register.jsf
/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>上*.xhtml加上一个空值<auth- constraint>,web.xml以防止出现以下情况:
<security- constraint>
<url-pattern>
<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>
2017年4月推出的JSF 2.3已通过在webapp启动期间自动注册FacesServletURL模式来解决以上所有问题*.xhtml。因此,替代方法是简单地升级到最新可用的JSF版本,该版本应为JSF2.3或更高版本。但是理想情况下,您仍然应该FacesServlet仅在一种URL模式上显式注册,*.xhtml因为对于完全相同的资源/register.xhtml(/register.jsf,)具有多个可能的URL,/register.faces并且/faces/register.xhtml对SEO不利。
/register.faces
自从JSF 2.2引入以来,另一个可能的原因是XML名称空间与JSF版本不匹配。该xmlns.jcp.org像下面是因为JSF 2.2新不旧的在JSF版本的工作。症状几乎与FacesServlet未调用相同。
xmlns.jcp.org
<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.comXML名称空间:
java.sun.com
<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">
但理想情况下,应始终使用可用的最新版本。
另一个可能的原因是您的Web应用程序已加载了多个JSF实现,它们相互冲突并破坏。例如,当您的Web应用程序的运行时类路径被多个不同版本的JSF库污染,或者在特定的Mojarra 2.x + Tomcat 8.x组合中被污染时,Web ConfigureListener应用程序中有不必要的条目会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时,请绝对确保以正确的方式声明依赖关系,并了解依赖关系范围。重要的是,当目标服务器已经提供依赖时,请不要在webapp中捆绑它们。
对于不熟悉基本HTTP,HTML和Servlet的人,JSF的学习曲线非常陡峭。Internet上有很多低质量的资源。请忽略由业余人员维护的代码片段抓取站点,这些站点主要侧重于广告收入而不是教学,例如roseindia,tutorialspoint,javabeat等。通过扰乱广告链接/横幅很容易识别它们。另外,请忽略处理侏罗纪JSF1.x的资源。通过使用JSP文件而不是XHTML文件,可以轻松识别它们。自2009年JSF 2.0以来,已不推荐使用JSP作为视图技术。
要以正确的方式入门,请从我们的JSF Wiki页面开始并订购一本权威书籍。