Какой URL-адрес использовать для связи/перехода на другие страницы JSF

Я запутался в том, как связывать файлы в проекте Java Server Faces, когда некоторые из файлов находятся в подпапках. (Я собирался приложить скриншоты, чтобы вы могли видеть проект проекта Nebeans и просмотр файлов в примере, который я пытаюсь... но мне еще не разрешено добавлять изображения).

В моем примере проекта у меня есть файлы, называемые "index.xhtml" и "calculate/calculate.xhtml". У меня также есть файл под названием "template.xhtml", который используется обоими. Вопрос в том, какой формат URL должен использоваться в шаблоне, который будет работать для обоих файлов.

В прямом html я просто использовал бы что-то вроде следующего, чтобы предоставить ссылку на домашнюю страницу, которая будет работать из любого места:

<a href="/index.html">Home</a>

Но я не могу понять, что считается корневой папкой для приложения JSF, и использовать ли структуру папок проекта или структуру каталогов файлов.

Ответ 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" />

См. также: