我有这样的结构:
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是基于相关资源的真实公共web地址进行解析的。也就是说,调用它们的是浏览器,而不是web服务器。
有几种方法可以减轻痛苦:
JSF EL提供了#{request}
风格的${pageContext.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
的上下文根获取视图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()
,参见这个答案)
在生成的HTML中应该像
一样结束<base href="http://example.com/webname/" />
注意<base>
标签有一个警告:它使页面中的所有跳转锚(如<a href="#top">
)也相对于它!另请参阅是否建议使用
<a href="#{request.requestURI}#top">top</a>
或<h:link value="top" fragment="top" />
那样解决它。从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}" />