如何获得基地url?

我有这样的结构:

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。 我不能使用相对path,因为它也会产生错误的URL。 我认为这是因为组件是基于*.xhtml页面的当前path。

我唯一能find的解决scheme是:

 <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不是基于服务器端的文件结构来parsing的。 url是根据相关资源的真实公共urlparsing的。 它是必须调用它们的浏览器,而不是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,并且会自动附加上下文path和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">相对于它! 另请参阅build议使用<base> html标记吗? 在JSF中,您可以像<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}" />