JSF使用plain / raw XHTML / XML / EL源返回空白/未分析的页面,而不是呈现的HTML输出
我有一些像下面的Facelets文件。
的WebContent | - index.xhtml | - register.xhtml | - 模板 | | --userForm.xhtml | `--banner.xhtml :
这两个页面都使用来自/templates
目录的/templates
。 我的/index.xhtml
在浏览器中打开。 我得到了生成的HTML输出。 我在/index.xhtml
文件中链接到/register.xhtml
文件。 但是,我的/register.xhtml
没有得到parsing,并返回为纯XHTML /原始XML而不是其生成的HTML输出。 当我在浏览器中右键单击页面并执行查看页面源代码时 ,我仍然可以看到XHTML源代码,而不是生成的HTML输出。 它看起来像模板没有得到应用。
但是,当我在浏览器的地址栏中打开/register.xhtml
/faces/register.xhtml
时,它显示正确。 这是如何造成的,我该如何解决?
有三个主要原因。
-
FacesServlet
不被调用。 - XML名称空间URI丢失或错误。
- 已经加载了多个JSF实现。
1.确保URL匹配FacesServlet
映射
链接的URL(您在浏览器地址栏中看到的URL)必须与web.xml
中定义的FacesServlet
的<url-pattern>
匹配,才能使所有JSF作品运行。 FacesServlet
负责parsingXHTML文件,收集提交的表单值,执行转换/validation,更新模型,调用动作和生成HTML输出。 如果你不通过URL调用FacesServlet
,那么你所得到的(通过右键单击,在浏览器中查看源代码 )确实是原始的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
,那么您可能还想阻止最终用户通过URL直接访问XHTML源代码文件。 在这种情况下,您可以在*.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将通过在webapp启动期间自动在*.xhtml
的URL模式中注册FacesServlet
来解决上述所有问题。
也可以看看:
- 在JSF项目中通过<welcome-file>设置默认主页
- “这个XML文件似乎没有任何关联的样式信息”,打开Facelets页面错误。
- JSF Facelets:有时我会看到URL是.jsf,有时是.xhtml。 为什么?
- JavaServer Faces 2.2和HTML5支持,为什么仍然使用XHTML
- 我需要将哪些XHTML文件放在/ WEB-INF中,哪些不是?
- 我们的servlets维基 – 了解有关servlet的强制性基础知识
2.确保XML名称空间与JSF版本匹配
自引入JSF 2.2以来,另一个可能的原因是XML名称空间与JSF版本不匹配。 下面的xmlns.jcp.org
是自JSF 2.2以来的新增function,在旧的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">
也可以看看:
- 哪一个XML命名空间与JSF 2.2一起使用
- JSF标签没有执行
- 警告:此页面调用XML名称空间http://xmlns.jcp.org/jsf/XXX,其前缀为XXX,但该名称空间不存在taglibrary
3.多个JSF实现已经加载
另一个可能的原因是多个JSF实现已经被你的web应用程序加载,相互冲突和破坏。 例如,当webapp的运行时类path受到多个不同的版本化的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>
在使用Maven时,要确保以正确的方式声明依赖关系,并理解依赖范围。 重要的是,当目标服务器已经提供了这些依赖关系的时候,不要将这些依赖关系捆绑在一起。
也可以看看:
- com.sun.faces.config.ConfigureListener的configuration
- 如何通过Maven正确安装和configurationJSF库?
确保你以正确的方式学习JSF
对于那些不熟悉基本HTTP , HTML和Servlets的人来说,JSF的学习曲线非常陡峭。 互联网上有很多低质量的资源。 请忽略业余爱好者维护的代码片段抓取网站,主要关注广告收入,而不是Roseindia,tutorialspoint,javabeat等教学,他们很容易被干扰性的广告链接/横幅所识别。 也请忽略处理jurassic JSF 1.x的资源。 他们很容易通过使用JSP文件而不是XHTML文件来识别。 从2009年的JSF 2.0开始,JSP作为视图技术已经被弃用了。
要开始正确的方法,请从我们的JSF wiki页面开始 ,订购一本权威书籍 。
也可以看看:
- Java EE web开发,我从哪里开始,我需要什么技能?
- 当用户界面可以通过CSS,HTML,JavaScript,jQuery实现时,JSF有什么需要?