3

我一直在检查,无法找到有关 FacesServlet 如何将 URL 解析为 Web 应用程序文件结构中的真实文件的解释。在 servlet 的上下文中,我的理解是 URL 只是您希望客户端使用的虚构名称。然后,在 web.xml 中,您将特定的 servlet 映射到 URL 模式,但是 servlet 的真实名称/位置对外界是隐藏的……这通常适用于 servlet。

特别是对于 JSF 2,我们处理 FacesServlet,这引出了我的第一个问题:FacesServlet 是我需要在我的应用程序中提供映射详细信息的唯一 servlet(也是我唯一需要的 servlet,期间)?答案似乎是“是”,但如果在某些情况下并非如此,请举个例子。

通过阅读关于 SO 的其他问题,我了解到并非所有请求都需要通过 FacesServlet,因此基本上请求分为 A)对不应该由 FacesServlet 处理的静态内容的请求,和 B)对动态内容的请求需要由 FacesServlet 处理。那么,静态内容是如何获得的呢?只是通过传入的请求,其中的 URL 与 FacesServlet 的 URL 模式不匹配,但匹配应用程序文件结构中的真实文件位置?

最后,我的主要问题是:当一个请求与 FacesServlet 的 URL 模式匹配时,FacesServlet 如何知道要呈现哪个视图文件 (.xhtml)?在使用 JSF 2 时是否有一个约定,我需要遵循它才能使其工作?如果不是,那么我不明白,因为就像我在上面提到的“通用”servlet 的情况下,URL 可以包含一个与真实文件名无关的名称,只要它映射到web.xml 文件中的正确 servlet。我觉得我在这里遗漏了一些明显(和重要)的东西。我唯一能想到的是 URL 应该匹配一个真实的文件位置,或者有另一个映射表或将 URL 与视图文件相关联的东西。

顺便说一句,我看了这个问题,它是相关的,但没有任何答案。

谢谢!

4

1 回答 1

1

servlet 规范第 10.5 节概述了提供静态内容的最简单方法:

Web 应用程序作为目录的结构化层次结构存在。此层次结构的根用作作为应用程序一部分的文件的文档根。例如,对于在 Web 容器中具有上下文路径 /catalog 的 Web 应用程序,index.html 文件位于 Web 应用程序层次结构的基础或 WEB-INF/lib 内的 JAR 文件中,其中包含 META 下的 index.html -INF/resources 目录可以满足来自 /catalog/index.html 的请求。如果 index.html 存在于根上下文和应用程序 WEB-INF/lib 目录中 JAR 文件的 META-INF/resources 目录中,则必须使用根上下文中可用的文件. 第 12 章“将请求映射到 Servlet”中列出了将 URL 与上下文路径匹配的规则。

应用程序层次结构中存在一个名为“WEB-INF”的特殊目录。此目录包含与应用程序相关但不在应用程序文档根目录中的所有内容。大多数 WEB-INF 节点不是应用程序的公共文档树的一部分。除了静态资源和封装在 WEB-INF/lib 目录下的 JAR 文件的 META-INF/resources 中的 JSP 之外,WEB-INF 目录中包含的其他文件不能由容器直接提供给客户端。

也就是说,要提供静态内容,将内容保存在 Web 应用程序的适当目录中就足够了。

Servlet 映射是对这个“隐式”servlet 的补充。因此,大多数 JSF 应用程序只声明 FacesServlet。IIRC,在最近的 JSF 实现中,如果省略了它的声明,servlet 甚至会声明自己,因此您甚至不必显式声明它。

FacesServlet 如何定位要使用的视图的定义在JSF 规范中定义,特别是第 7.6.2 节:

术语视图标识符和 viewId 在下面可互换使用,表示生成视图的 Web 应用程序资源的上下文相对路径,例如 JSP 页面或 Facelets 页面。在 JSP 情况下,这是表示视图的 jsp 页面的上下文相对路径,例如 /foo.jsp。在 Facelets 案例中,这是表示视图的 XHTML 页面的上下文相对路径,例如 /foo.xhtml。

JSF 实现必须提供默认 ViewHandler 实现,以及提供 ViewDeclarationLanguage 实现的默认 ViewDeclarationLanguageFactory 实现,这些实现旨在支持呈现包含 JSF 组件的 JSP 页面和包含 JSF 组件的 Facelets 页面。

默认实现在以下 7.6.2.1 节中指定。我饶了你的完整报价。要点是,如果 Faces Servlet 使用前缀映射(例如/faces/**)进行映射,则 viewId 是 URL 中前缀之后的部分,如果 Faces Servlet 使用后缀映射(例如*.jsf)进行映射,则 viewId 是部分上下文路径后面的 URL 的名称,并带有替换的文件扩展名。例如,如果 servlet 映射到*.jsf,则对 URL 的请求将从Web 应用程序目录中http://host/context/admin/userlist.jsf的文件中读取视图定义。admin/userlist.xhtml

于 2013-04-07T17:04:58.430 回答