我有这个结构:
WebContent
resources
components
top.xhtml
company
about_us.xhtml
index.xhtml
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,当当前页面是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>
Run Code Online (Sandbox Code Playgroud)
但我认为根本不是"优雅".有任何想法吗?
Bal*_*usC 144
不会根据服务器端的文件结构解析URL.根据相关资源的真实公共网址解析URL.这就是webbrowser必须调用它们,而不是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>
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以使用<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>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
(注意:这需要EL 2.2,否则你最好使用JSTL fn:substring()
,另见这个答案)
这应该最终生成的HTML类似于
<base href="http://example.com/webname/" />
Run Code Online (Sandbox Code Playgroud)
请注意,<base>
标记有一个警告:它使页面中的所有跳跃锚也<a href="#top">
相对于它!另请参阅是否建议使用<base> html标记?在JSF中你可以像<a href="#{request.requestURI}#top">top</a>
或那样解决它<h:link value="top" fragment="top" />
.