73

我有这个结构:

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>

但我认为一点也不“优雅”。有任何想法吗?

4

2 回答 2

156

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

有几种方法可以减轻疼痛:

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" />

于 2011-07-29T20:00:23.693 回答
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}" />
于 2015-06-17T04:41:27.697 回答