在 JSF 项目中通过 <welcome-file> 设置默认主页

Posted

技术标签:

【中文标题】在 JSF 项目中通过 <welcome-file> 设置默认主页【英文标题】:Set default home page via <welcome-file> in JSF project 【发布时间】:2015-02-18 04:45:54 【问题描述】:

当我使用 Eclipse 中的 Tomcat 8.0 启动 Java EE 项目时,我无法设置在浏览器中加载的默认页面。 我正在努力学习JSF,所以我关注了this tutorial

一切正常,但是当我右键单击login.xhtmlwelcome.xhtml 文件并选择“运行方式/在服务器上运行”时,我只能看到创建的页面。

到目前为止,当我启动整个项目时,我创建的所有其他 Web 应用程序都加载了默认页面。默认行为是加载index.html 页面(或者可能是 index.jsp,如果有的话)。所以我将index.htmlindex.xhtml 页面添加到项目的WEB-INF 文件夹中,希望至少显示其中一个。然而,什么也没有发生。浏览器总是只显示localhost:8080/JSFFaceletsTutorial/ URL 上的页面,但页面是白色的,甚至没有错误消息。我想我在解决这个问题的过程中一直遇到错误 404,但是,我不再能够重现这个错误,我不记得是什么原因造成的。

我发现可以change the default starting page

但是,它对我也不起作用。无论我是否编辑web.xml 文件,我都会得到相同的结果。

更令人费解的是,当我尝试更改 Web 浏览器:“Window/Web Browser/...”时,它在外部 Web 浏览器中的行为与在内部 Eclipse Web 浏览器中的行为有一段时间不同。内部总是空白页——但外部网络浏览器曾经设法显示index.html 页面——但它是一些过时的版本。尽管我绝对确定我编辑了它,保存了更改,重新启动了服务器......但它仍然向我展示了页面的过时版本。 即使在这种情况下,它仍然忽略了在web.xml 文件中所做的更改。 但是当我现在尝试它时,它再次在所有浏览器中显示空白页。除了编辑web.xml 文件外,我不知道我所做的任何更改...

我的猜测是问题出在我还没有完全掌握的 JSF 技术上。这是因为当我选择使用右键单击“运行方式/在服务器上运行”来运行login.xhtmlwelcome.xhtml 页面时,这些页面的URL 位于localhost:8080: 上,路径为/JSFFaceletsTutorial/faces/login.xhtml/JSFFaceletsTutorial/faces/welcome.xhtml。这很奇怪,因为我的项目中没有任何目录“面孔”。 键入以下所有可能的排列:

<welcome-file-list>
    <welcome-file>faces/index.html</welcome-file>
    <welcome-file>faces/index.xhtm</welcome-file>
</welcome-file-list>

web.xml 也没有帮助。当我在那里输入完整地址时,它也没有帮助。

这是我在控制台中收到的警告(我跳过了 INFO 日志条目):

“2014 年 12 月 19 日上午 9:39:55 org.apache.tomcat.util.digester.SetPropertiesRule 开始 警告:[SetPropertiesRule]Server/Service/Engine/Host/Context 将属性 'source' 设置为 'org.eclipse.jst.jee.server:JSFFaceletsTutorial' 没有找到匹配的属性。 ... 警告:JSF1074:名为“loginBean”的托管 bean 已注册。用 com.tutorial.LoginBean 替换现有的托管 bean 类类型 com.tutorial.LoginBean。 2014 年 12 月 19 日上午 9:39:57 org.apache.coyote.AbstractProtocol 开始"

我不确定这是否有用。 我现在没有主意了。

【问题讨论】:

我认为它只是 index.xhtml?您所有的文件都命名为 .xhtml?所以这将是第一个猜测。请注意,如果您使用 JSF servlet (*.jsf) 的 servlet 映射来指向 .xhtml 文件,则欢迎文件将无法获取它。它必须是物理文件。 【参考方案1】:

首先,&lt;welcome-file&gt; 不代表“默认主页”的路径。它表示文件夹中包含的物理文件的文件名,当请求//foo//foo/bar/文件夹 时,您希望将其用作默认文件。

因此,在 JSF 2.x 风格中,基本上是:

<welcome-file-list>
    <welcome-file>index.xhtml</welcome-file>
</welcome-file-list>

这样,如果最终用户请求/ 而你有/index.xhtml,那么它将被提供。或者,如果最终用户请求/foo,而你有/foo/index.xhtml,那么它将被提供,等等。如果没有这样的文件,则会返回404错误。

现在,您似乎已将您的FacesServlet 映射到/faces/* 的前缀&lt;url-pattern&gt;。这是 JSF 1.0/1.1 时代的遗留物,现在真的不推荐。可能您正在阅读针对 JSF 1.x 的过时教程,或者是最初为 JSF 1.x 编写的教程维护不善,然后针对 JSF 2.x 进行了粗心的更新,而不是从头开始重写。

该教程似乎也没有向您解释some servlet basics。即,为了让 XHTML 页面中的 JSF 组件运行并生成一些 HTML 输出,必须在请求 XHTML 页面时调用 FacesServlet。当您像/index.xhtml 那样请求XHTML 页面时,而FacesServlet 被映射到/faces/*,则不会调用它。然后,浏览器将检索原始的未解析 JSF 源代码,而不是生成的 HTML 输出。您可以通过在浏览器中单击鼠标右键,查看源代码来查看它。您应该像 /faces/index.xhtml 这样请求页面,以便 FacesServlet 可以运行并生成浏览器可以理解和呈现的 HTML 输出。

这只是与欢迎文件搭配得不好。这完全解释了为什么在使用 index.xhtml 作为欢迎文件时会得到一个“干净的白色”(空白)页面(一些劣质网络浏览器,如 IE 会混淆 prompt a download dialog,因为包含原始 XHTML 源代码的响应中缺少/错误的内容类型) . FacesServlet 根本没有被调用。只需摆脱老式的 /faces/* URL 模式,改用 JSF 2.x 的 *.xhtml URL 模式。

<servlet-mapping>
    <servlet-name>facesServlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

通过这种方式欢迎文件应该可以工作,您可以通过直接请求其物理 URL 来打开 JSF 页面,而无需使用虚拟 URL。这在 JSF 1.x 中是不可能的,因为它会让 FacesServlet 在无限循环中运行并调用自身并导致堆栈溢出。

另见:

JSF Facelets: Sometimes I see the URL is .jsf and sometimes .xhtml. Why? Setting application URL on WAS server, where does /faces/ come from? What is the difference between creating JSF pages with .jsp or .xhtml or .jsf extension Why can web.xml welcome-file be located inside WEB-INF How to use a sub-folder as web.xml welcome directory

至于这些警告,它们不相关,但可以通过谷歌搜索。

【讨论】:

是的,我知道它只代表物理文件。我只是没有解释清楚。我并没有尝试默认运行这些页面 login.xhtml 和 welcome.xhtml。我试图创建一个带有指向此登录页面的链接的新页面。该新页面将只是一个新的简单物理文件。我知道 servlet,几年前我正在处理 jsp 页面。虽然特别感谢第三个链接。它会派上用场的。它现在可以工作了,这是 servlet-mapping 标签的问题。有趣的是,这在 JSF 1 中是不允许的... @BalusC 我目前正在处理这个问题。我想要自定义映射,所以我用*.html 替换了/faces/*。但是,我的索引页的行为出乎意料。我试过&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;,但它只在左上角显示我的标题(我正在使用模板,&lt;ui:composition&gt;。当我检查源代码时,它显示索引文件本身的源代码。如果我把xhtml 回来了,欢迎文件和映射都恢复了 【参考方案2】:

我认为这会起作用

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.xyz.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.xyz.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <welcome-file-list>
    <welcome-file>/main/login.xhtml</welcome-file>
      </welcome-file-list>
<!--         <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.xyz.servlets.login</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping> -->

</web-app>

【讨论】:

【参考方案3】:

您可以在 web.xml 文件中设置默认页面,以通过两种方式在 JSF 中调用 facesServlet:

<web-app xmlns="http://xmlns.xyz.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.xyz.org/xml/ns/javaee http://xmlns.xyz.org/xml/ns/javaee/web-app_4_0.xsd"
     version="4.0">
    <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>
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

或直接从欢迎文件中调用 facesServlet,如下所示:

<web-app xmlns="http://xmlns.xyz.org/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.xyz.org/xml/ns/javaee http://xmlns.xyz.org/xml/ns/javaee/web-app_4_0.xsd"
 version="4.0">
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

希望对大家有所帮助!

【讨论】:

以上是关于在 JSF 项目中通过 <welcome-file> 设置默认主页的主要内容,如果未能解决你的问题,请参考以下文章

在 JSF 1.2 中通过 EL 调用带参数的方法

在其他模块的 JSF ManagedBean 中通过 @EJB(lookup) 注入远程无状态 EJB

在 PrimeFaces 3.4 JSF 2.0 中按 id 查找组件

java项目中通过添加filter过滤器解决ajax跨域问题

Maven中通过parent项目的pom维护第三方依赖

项目结构