Ответ 1
Прежде всего, JSF является генератором кода HTML. Поэтому в JSF это не так, как в "простом" HTML. Вы должны просто не смотреть на структуру файловой системы в проекте webapp при создании ссылок в HTML. Вы должны посмотреть на общедоступную структуру URL этих ресурсов. Это именно веб-браузер, которому приходится вызывать и загружать эти ресурсы, а не веб-сервер. Веб-браузер абсолютно ничего не знает о структуре файловой системы на веб-сервере. Это не относится к проектам JSF. Это относится ко всем веб-проектам.
Относительные URL-адреса не относятся к их местоположению в структуре файловой системы в проекте webapp. Они относятся к URL-адресу запроса открытого HTML-документа, точно такого, который вы видите в адресной строке браузера. Следует отметить, что если элемент <base>
присутствует в документе HTML, то все относительные URL-адреса в документе HTML, начиная с /
, будут относиться к нему.
Учитывая webapp, который настроен с шаблоном URL-адреса FacesServlet
для *.xhtml
и развернут на localhost:8080
с контуром пути /context
, URL-адрес файла /index.xhtml
в корне веб-сайта проекта будет быть ниже:
http://localhost:8080/context/index.xhtml
---- -------------- ------- -----------
| | | `-- resource
| | `-- path (can be multiple folders)
| `-- domain (and port)
`-- scheme
Если вы в настоящее время находитесь в http://localhost:8080/context/index.xhtml
, и хотите создать ссылку на http://localhost:8080/context/calculate/calculate.xhtml
, то все приведенные ниже пути в конечном итоге указывают на абсолютно тот же абсолютный URL.
-
Относительный URL, начинающийся с
//
, относится к текущей схеме.<a href="//localhost:8080/context/calculate/calculate.xhtml">link</a>
-
Относительный URL, начинающийся с
/
, относится к домену.<a href="/context/calculate/calculate.xhtml">link</a>
-
Относительный URL, не начинающийся с
/
, относится к пути.<a href="calculate/calculate.xhtml">link</a>
И когда вы в настоящее время находитесь в
http://localhost:8080/context/calculate/calculate.xhtml
, и вы хотите установить ссылку на http://localhost:8080/context/index.xhtml
, тогда применяются те же правила:
-
Относительный URL, начинающийся с
//
, относится к текущей схеме.<a href="//localhost:8080/context/index.xhtml">link</a>
-
Относительный URL, начинающийся с
/
, относится к домену.<a href="/context/index.xhtml">link</a>
-
Относительный URL, не начинающийся с
/
, относится к пути.<a href="../index.xhtml">link</a>
Как вы, вероятно, понимаете, относительный URL, начинающийся с /
, не зависит от текущего пути и домена. Итак, этот URL-адрес, который вы действительно хотите использовать повсюду в своем веб-приложении, не беспокоясь о проблемах обслуживания при изменении домена или перемещении файлов на сервере. Остается только динамичность контекстного пути. Вероятно, вы уже знаете, что это значение не контролируется внутри webapp. Вы действительно хотели бы избежать его жесткого кодирования. Однако вы можете легко позволить JSF распечатать его программно с небольшой помощью EL. Это просто доступно HttpServletRequest#getContextPath()
, а HttpServletRequest
находится в EL, доступном как неявный объект #{request}
.
<a href="#{request.contextPath}/index.xhtml">link</a>
<a href="#{request.contextPath}/calculate/calculate.xhtml">link</a>
Только утомительно повторять это каждый раз. К счастью, JSF предлагает компонент <h:link>
для самой цели генерации элемента HTML <a>
с текущим контуром контекста автоматически.
<h:link value="link" outcome="index.xhtml" />
<h:link value="link" outcome="calculate/calculate.xhtml" />
Обратите внимание, что outcome
должен представлять идентификатор вида JSF, который не обязательно совпадает с URL-адресом (он будет отображаться при FacesServlet
на *.xhtml
). Вы даже можете опустить расширение файла здесь, JSF автоматически обнаружит его как часть механизма "неявной навигации".
<h:link value="link" outcome="index" />
<h:link value="link" outcome="calculate/calculate" />
См. также:
- Рекомендуется ли использовать <base> html-тег?
- Каковы эти URL-адреса, начинающиеся с //, которые вы видите в источнике Google+ html?
- JSF Facelets: Иногда я вижу URL-адрес .jsf и иногда .xhtml. Почему?
- Неявные объекты в EL
- Как перемещаться в JSF? Как сделать URL-адрес текущей страницы (а не предыдущей)