Ответ 1
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>
, который может принимать идентификатор вида относительно корня контекста в 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 tag? В JSF вы можете решить его как <a href="#{request.requestURI}#top">top</a>
или <h:link value="top" fragment="top" />
.