我有这样的结构:
WebContent
resources
components
top.xhtml
company
about_us.xhtml
index.xhtml
top.xhtml
是一个组件,也在 index.xthml
和 about_us.xhtml
中使用。
top.xhtml
<ul>
<li><a href="index.xhtml">Home</a></li>
<li><a href="company/about_us.xhtml">About us</a></li>
...
</ul>
所以我的问题是,当当前页面是 index.xhtml
时,组件会正确生成 URL,但是当当前页面是 about_us.xhtml
时,它会生成错误的 URL 。我不能使用相对路径,因为它也会生成错误的 URL。我认为这是因为该组件是基于 *.xhtml
页面的当前路径的。
我能找到的唯一解决方案是:
<ul>
<li><a href="${pageContext.request.contextPath}/webname/index.xhtml">Home</a></li>
<li><a href="${pageContext.request.contextPath}/webname/about_us.xhtml">About us</a></li>
...
</ul>
但我认为一点也不‘优雅’。有什么想法吗?
最佳答案
URL 不会根据服务器端的文件结构进行解析。 URL 是根据相关资源的真实公共(public)网址进行解析的。即是网络浏览器必须调用它们,而不是网络服务器。
有几种方法可以减轻疼痛:
JSF EL 提供了 ${pageContext.request}
的简写形式味道 #{request}
:
<li><a href="#{request.contextPath}/index.xhtml">Home</a></li>
<li><a href="#{request.contextPath}/about_us.xhtml">About us</a></li>
如有必要,您可以使用 <c:set>
标签以使其更短。将其放在主模板中的某个位置,它将可供所有页面使用:
<c:set var="root" value="#{request.contextPath}/" />
...
<li><a href="#{root}index.xhtml">Home</a></li>
<li><a href="#{root}about_us.xhtml">About us</a></li>
JSF 2.x 提供 <h:link>
它可以获取相对于outcome
中的上下文根的 View ID它将附加上下文路径和 FacesServlet
自动映射:
<li><h:link value="Home" outcome="index" /></li>
<li><h:link value="About us" outcome="about_us" /></li>
HTML 提供 <base>
标签使文档中的所有相对 URL 都相对于此基础。你可以利用它。将其放入 <h:head>
.
<base href="#{request.requestURL.substring(0, request.requestURL.length() - request.requestURI.length())}#{request.contextPath}/" />
...
<li><a href="index.xhtml">Home</a></li>
<li><a href="about_us.xhtml">About us</a></li>
(注意:这需要 EL 2.2,否则你最好使用 JSTL fn:substring()
,另请参阅 this answer )
这应该最终出现在生成的 HTML 中,类似于
<base href="http://example.com/webname/" />
请注意 <base>
标签有一个警告:它使页面中的所有跳转 anchor 像 <a href="#top">
也相对于它而言!另请参阅Is it recommended to use the <base> html tag?在 JSF 中你可以像 <a href="#{request.requestURI}#top">top</a>
那样解决它或<h:link value="top" fragment="top" />
.
关于jsf - 如何通过 JSF 中的上下文路径获取基本 URL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7459779/