如何通过JSF中的上下文路径获取基本URL?


69

我有这个结构:

WebContent
    resources
        components
            top.xhtml

    company
        about_us.xhtml

    index.xhtml

top.xhtml是一个组件,也用于index.xthmlabout_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>

但是我认为这根本不是“优雅”的。有任何想法吗?

Answers:


149

无法根据服务器端的文件结构解析URL。URL是根据相关资源的真实公共网址解析的。是必须调用它们的是Web浏览器,而不是Web服务器。

有几种减轻疼痛的方法:

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>一个可以获取相对于上下文根的视图ID的视图outcome,它将自动附加上下文路径和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(),另请参见此答案

这应该最终出现在生成的HTML中,例如

<base href="http://example.com/webname/" />

请注意,该<base>标记有一个警告:它会使页面中的所有跳转锚点也<a href="#top">相对于它!另请参见是否建议使用<base> html标签?在JSF中,您可以像<a href="#{request.requestURI}#top">top</a>或那样解决它<h:link value="top" fragment="top" />


3
非常感谢您,我是您的忠实支持者=)我希望当您成为队友时成为一名出色的开发人员,谢谢。
Valter Silva

不错的解决方案,不知道那是可能的!感谢分享!
罗伯特M.11年

1
@balusC是的,ui:param方法不适用于myfaces。
拉贾特·古普塔

1
@Aklin:我确定了答案,谢谢,我不知道这是针对Mojarra的,实际上我也从未见过有关Mojarra的问题报告。
BalusC 2012年

1
@Aklin:也许又是MyFaces的另一件事。尝试添加scope="request"
BalusC 2012年

1

BalusC答案利用了JSTL 1.2版本

<c:set var="baseURL" value="${pageContext.request.requestURL.substring(0, pageContext.request.requestURL.length() - pageContext.request.requestURI.length())}${pageContext.request.contextPath}/" />

<head>
  <base href="${baseURL}" />
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.