用于链接/导航到其他 JSF 页面的 URL
Posted
技术标签:
【中文标题】用于链接/导航到其他 JSF 页面的 URL【英文标题】:What URL to use to link / navigate to other JSF pages 【发布时间】:2015-08-21 09:51:26 【问题描述】:当一些文件位于子文件夹中时,我对如何在 Java Server Faces 项目中的文件之间进行链接感到困惑。 (我打算附上屏幕截图,以便您可以看到 Nebeans 项目视图和我正在尝试的示例的文件视图......但我还不允许添加图像)。
在我的示例项目中,我有名为“index.xhtml”和“calculate/calculate.xhtml”的文件。我还有一个名为“template.xhtml”的文件,两者都使用。问题是在模板中使用哪种 url 格式适用于这两个文件。
在直接的 html 中,我将使用类似以下的内容来提供返回主页的链接,该链接可在任何位置工作:
<a href="/index.html">Home</a>
但我不知道什么是 JSF 应用程序的根文件夹,以及是使用“项目视图”文件夹结构还是“文件列表”文件夹结构。
【问题讨论】:
模板文件仅通过<ui:include src="...">
和<ui:insert name="...">
的方式包含在服务器端。客户端可以请求与该 URL 关联的资源的目标 URL 没有区别。迁移到 JSF 后,您观察到什么不同?
在我的模板中,如果我使用以下行:
在我的模板中,如果我使用<a href="/index.xhtml" ..
,那么 glassfish 服务器会认为它是http://localhost:8080/index.xhtml
。但是,如果我使用<a href="index.xhtml" ..
,那么索引文件应该与 xhtml 文件位于同一文件夹中......所以我很困惑该怎么做
【参考方案1】:
首先,JSF 是一个 HTML 代码生成器。所以它在 JSF 中与在“普通”HTML 中没有什么不同。在 HTML 中创建链接时,您不应该只查看 webapp 项目中的文件系统结构。您应该查看这些资源的公共 URL 结构。即必须调用和下载这些资源的是网络浏览器,而不是网络服务器。网络浏览器对网络服务器中的文件系统结构一无所知。这并不特定于 JSF 项目。这适用于所有网络项目。
相对 URL 与其在 webapp 项目的文件系统结构中的位置无关。它们与当前打开的 HTML 文档的请求 URL 相关,正是您在浏览器地址栏中看到的那个。需要注意的是,当 HTML 文档中存在 <base>
元素时,HTML 文档中所有不以 /
开头的相对 URL 都将变为相对于它。
给定一个配置了FacesServlet
映射URL模式*.xhtml
的webapp,并以/context
的上下文路径部署到localhost:8080
,项目Web根目录中/index.xhtml
文件的URL将如下:
http://localhost:8080/context/index.xhtml
---- -------------- ------- -----------
| | | `-- resource
| | `-- path (can be multiple folders)
| `-- domain (and port)
`-- scheme
如果您当前位于http://localhost:8080/context/index.xhtml
,并且想要创建指向http://localhost:8080/context/calculate/calculate.xhtml
的链接,那么以下所有方式最终都会指向完全相同的绝对 URL。
以//
开头的相对 URL 是相对于当前方案的。
<a href="//localhost:8080/context/calculate/calculate.xhtml">link</a>
以/
开头的相对 URL 是相对于域的。
<a href="/context/calculate/calculate.xhtml">link</a>
以/
开头的相对URL不是相对于路径的。
<a href="calculate/calculate.xhtml">link</a>
当你目前在
http://localhost:8080/context/calculate/calculate.xhtml
,并且你想链接到http://localhost:8080/context/index.xhtml
,那么同样的规则适用:
以//
开头的相对 URL 是相对于当前方案的。
<a href="//localhost:8080/context/index.xhtml">link</a>
以/
开头的相对 URL 是相对于域的。
<a href="/context/index.xhtml">link</a>
以/
开头的相对URL不是相对于路径的。
<a href="../index.xhtml">link</a>
您现在可能已经意识到,以/
开头的相对 URL不依赖于当前路径和域。因此,这就是您真正希望在 Web 应用程序中随处使用的 URL,而不必担心在更改域或在服务器中移动文件时出现维护问题。唯一剩下的就是上下文路径的动态性。您可能已经知道这个值在 webapp 内部是无法控制的。您真的很想避免对其进行硬编码。但是,您可以在 EL 的帮助下轻松地让 JSF 以编程方式打印它。它仅由 HttpServletRequest#getContextPath()
提供,HttpServletRequest
在 EL 中可用作隐式对象 #request
。
<a href="#request.contextPath/index.xhtml">link</a>
<a href="#request.contextPath/calculate/calculate.xhtml">link</a>
每次重复此操作只会变得乏味。幸运的是,JSF 提供了<h:link>
组件,其目的就是为了生成一个HTML <a>
元素,并自动内联当前上下文路径。
<h:link value="link" outcome="index.xhtml" />
<h:link value="link" outcome="calculate/calculate.xhtml" />
注意outcome
必须代表一个JSF 视图ID,它不一定与URL 路径相同(当您将FacesServlet
映射到*.xhtml
时会这样)。您甚至可以在此处省略文件扩展名,JSF 会自动将其检测为“隐式导航”机制的一部分。
<h:link value="link" outcome="index" />
<h:link value="link" outcome="calculate/calculate" />
另见:
Is it recommended to use the <base> html tag? What are those URL's that are starting with // - that you can see within Google+ html source? JSF Facelets: Sometimes I see the URL is .jsf and sometimes .xhtml. Why? Implicit objects in EL How to navigate in JSF? How to make URL reflect current page (and not previous one)【讨论】:
很好的答案,谢谢!我在任何地方都找不到对这一切的体面描述。如果我缺少简明的文档资源,请告诉我。我正在研究Java EE 7 教程:第 1 卷:基本概念(Java 系列),但他们还没有涵盖这一点,而且他们的示例都没有在子文件夹中包含 xhtml 文件。我确实尝试过href="#request.contextPath/index.xhtml"
之前并没有真正理解它在做什么,我猜当时还有其他问题。无论如何它现在正在工作,谢谢。
不客气。它不完全是 JSF。它只是 HTTP 和 HTML。了解 HTTP 和 HTML 确实是深入 JSF 之前的先决条件。在这种特定情况下,学习 JSF 需要了解 <h:link>
和 #request.contextPath
的用途(尽管后者比 JSF 更特定于 Servlet+EL)。以上是关于用于链接/导航到其他 JSF 页面的 URL的主要内容,如果未能解决你的问题,请参考以下文章