FacesServlet如何根据URL知道要渲染哪个facelet?

时间:2013-04-07 16:06:37

标签: java-ee servlets jsf-2 url-routing facesservlet

我一直在检查,无法找到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与视图文件相关联的东西。

顺便说一句,我看了this question,这是相关的,但没有任何答案。

谢谢!

1 个答案:

答案 0 :(得分:1)

servlet specification第10.5节

概述了提供静态内容的最简单方法
  

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

  

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

也就是说,要提供静态内容,只需将内容保存在Web应用程序的相应目录中即可。

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

FacesServlet如何定位要使用的视图的定义在JSF specification中定义,特别是第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/**)映射Faces Servlet,则viewId是前缀后面的URL的一部分,并且如果Faces Servlet使用后缀映射进行映射(例如{{ 1}}),viewId是上下文路径后面的URL的一部分,替换了文件扩展名。例如,如果servlet映射到*.jsf,则对URL *.jsf的请求将从Web应用程序目录中的文件http://host/context/admin/userlist.jsf读取视图定义。