Как FacesServlet узнает, какой грань будет отображаться на основе URL?
Я проверял и не могу найти объяснение того, как FacesServlet разрешает URL-адрес в реальном файле в структуре файла веб-приложения. В контексте сервлетов я понимаю, что URL - это просто выдуманное имя, которое вы хотите, чтобы клиенты использовали. В web.xml вы затем сопоставляете конкретные сервлеты с шаблонами URL, но настоящее имя / местоположение сервлета скрыто от внешнего мира... это для сервлетов в целом.
Специально для JSF 2 мы имеем дело с FacesServlet, что приводит меня к моему первому вопросу: является ли FacesServlet единственным сервлетом, для которого мне нужно предоставить детали отображения в моем приложении (и единственный сервлет, который мне нужен, точка)? Кажется, что ответ "да", но если есть ситуации, когда это не так, приведите пример.
Из прочтения других вопросов по SO я понимаю, что не все запросы должны проходить через FacesServlet, поэтому в основном запросы делятся на A) запросы статического содержимого, которые не должны обрабатываться FacesServlet, и B) запросы динамического содержимого, которые должны быть обработаны FacesServlet. Итак, как получается статический контент? Просто при наличии входящего запроса, в котором URL-адрес не соответствует шаблону URL-адреса для FacesServlet, но соответствует ли реальное расположение файла в структуре файла приложения?
Наконец, мой главный вопрос: когда приходит запрос, который соответствует шаблону URL для FacesServlet, как FacesServlet узнает, какой файл представления (.xhtml) визуализировать? Есть ли соглашение по работе с JSF 2, которому я должен следовать, чтобы заставить его работать? Если нет, то я не понимаю, потому что, как я упоминал выше в случае "общего" сервлета, URL-адрес может содержать имя, которое не имеет ничего общего с реальным именем файла, если оно сопоставлено с правильный сервлет в файле web.xml. Я чувствую, что упускаю что-то очевидное (и важное) здесь. Единственное, о чем я могу думать, это то, что URL должен соответствовать реальному местоположению файла или что есть другая таблица сопоставления или что-то, что связывает URL с файлами представления.
Кстати, я посмотрел на этот вопрос, который связан, но не имеет ответов.
Спасибо!
1 ответ
Самый простой способ обслуживания статического контента описан в спецификации сервлета, раздел 10.5:
Веб-приложение существует в виде структурированной иерархии каталогов. Корень этой иерархии служит корнем документа для файлов, которые являются частью приложения. Например, для веб-приложения с контекстным путем / каталогом в веб-контейнере файл index.html в основе иерархии веб-приложения или в файле JAR внутри WEB-INF/lib, который включает в себя index.html в разделе META Каталог -INF / resources может обслуживаться для удовлетворения запроса из /catalog/index.html. Если index.html присутствует как в корневом контексте, так и в каталоге META-INF/resources файла JAR в каталоге WEB-INF/lib приложения, тогда ДОЛЖЕН использоваться файл, доступный в корневом контексте., Правила сопоставления URL-адресов с контекстным путем изложены в главе 12 "Отображение запросов на сервлеты".
а также
В иерархии приложения существует специальный каталог с именем "WEB-INF". Этот каталог содержит все вещи, связанные с приложением, которые не находятся в корне документа приложения. Большая часть узла WEB-INF не является частью дерева открытых документов приложения. За исключением статических ресурсов и JSP, упакованных в META-INF/resources файла JAR, который находится в каталоге WEB-INF/lib, никакие другие файлы, содержащиеся в каталоге WEB-INF, не могут быть переданы непосредственно клиенту контейнером.
То есть для обслуживания статического контента достаточно сохранить контент в соответствующем каталоге вашего веб-приложения.
Отображения сервлета являются дополнением к этому "неявному" сервлету. Поэтому большинство приложений JSF объявляют только FacesServlet. IIRC, в недавних реализациях JSF этот сервлет даже объявляет себя, если его объявление опущено, так что вам даже не нужно объявлять его явно.
То, как FacesServlet находит определение используемого представления, определено в спецификации JSF, в частности в разделе 7.6.2:
Термины идентификатор представления и viewId используются взаимозаменяемо ниже и означают относительный контекстный путь к ресурсу веб-приложения, которое создает представление, например страницу JSP или страницу Facelets. В случае JSP это контекстно-относительный путь к странице jsp, представляющей представление, например /foo.jsp. В случае Facelets это контекстно-относительный путь к странице XHTML, представляющей представление, например /foo.xhtml.
Реализации JSF должны предоставлять реализацию ViewHandler по умолчанию, а также реализацию ViewDeclarationLanguageFactory по умолчанию, которая реализует реализации ViewDeclarationLanguage, предназначенные для поддержки рендеринга страниц JSP, содержащих компоненты JSF, и страниц Facelets, содержащих компоненты JSF.
Реализация по умолчанию указана в следующем разделе 7.6.2.1. Я экономлю вашу полную цитату. Суть в том, что если сервлет Faces отображается с префиксным отображением (например, /faces/**
), viewId является частью URL-адреса, следующей за префиксом, и если сервлет Faces сопоставлен с суффиксным сопоставлением (например, *.jsf
), viewId - это часть URL-адреса, следующая за контекстным путем, с замененным расширением файла. Например, если сервлет сопоставлен с *.jsf
запрос на URL http://host/context/admin/userlist.jsf
будет читать определение представления из файла admin/userlist.xhtml
в каталоге веб-приложения.