ADF现在已经存在于我们的工程中了,接下来的问题就是它是怎么工作的了。换句话说,当我们的开发任务完成以后,把这个ADF项目部署到一个Java Web服务器上,当有浏览器对它发生请求的时候,我们的服务器怎么知道我这是一个JSF应用,进一步还会根据ArcGIS的ADF来生成那些乱七八糟的诸如WebContext之类的对象呢?
我们首先来看一下,当一个用户对服务器发送请求的时候,Java Web服务器怎么判断他要访问的是一个JSF应用。让我们打开“/WebContent/WEB-INF/web.xml”,这个web.xml文件是Java Web工程的部署描述文件,服务器会根据这个文件中的定义来加载Servlet以及其它的内容,在这个文件中我们可以分别找到下面两段定义:
“servlet”元素定义的是Java Web服务器加载的Servlet信息,“servlet-mapping”元素定义的是一个URL模式对应的Servlet,所有符合该URL模式的请求都会被映射到该Servlet上进行处理。在这里首先我们根据FacesServlet 这个类在服务器启动的时候加载了JSF的Servlet:“Faces Servlet”,然后又定义了一个“*.jsf”的URL模式,凡是以“*.jsf”出现的请求都会被映射到“Faces Servlet”进行处理。好了,到这里我们应该可以明白JSF是怎么工作的了。
在此基础上,我们需要进一步了解ADF的运行。还是在刚才的web.xml文件中,从中我们还可以找到以下的这段内容:
“listener”元素会根据相应的监听类配置一个监听。在这里模板工程为我们配置了一个ADFServletContextListener监听器,这个监听器实现了两个接口:ServletContextListener和HttpSessionListener。
ServletContextListener负责监听Web应用(你部署的这个ADF工程)的ServletContext的变化。当我们的Java Web服务器启动的时候,我们的Web应用也会跟着启动,这时,Web应用的ServletContext将会被创建并初始化,因此ADFServletContextListener的contextInitialized(ServletContextEvent event)方法会被调用。在这个方法中,ADF的WebApplication 会被创建并初始化。这个WebApplication相当于我们ADF的女娲娘娘,以下我们会看到一个又一个的ADF对象会从中孕育出来。
WebApplication中包含了由WebSession 组成的一个ArrayList,这个ArrayList中包含了所有的用户的ADF会话WebSession;当然,这个WebSession与整个Web应用的会话HttpSession 并不是独立的,WebSession会作为一个属性存储在HttpSession中。
在这个WebSession中其实也是一片广阔的革命天地。在每个WebSession中都会有一个由WebContext 组成的ArrayList,它存放的是这个会话所用到的所有WebContext对象。还记得WebContext么?在《ADF的逻辑结构》这小节中,WebContext是以一个非常大哥的形象出现的。现在发现,这个大哥其实是WebSession的小弟之一,WebSession则是WebApplication的小弟之一。
下面再说说HttpSessionListener,它负责监听Web应用当前会话的变化。当有一个新的用户向我们的服务器发送请求的时候,应用会为这个用户新建一个会话,这个时候,ADFServletContextListener的sessionCreated(HttpSessionEvent event)方法也会被执行(虽然事实上,在这里ADF并不做任何事情,WebSession并不是在这里创建,这个下面马上就讲);当一个会话结束时,ADFServletContextListener的sessionDestroyed(HttpSessionEvent event)方法会被执行,ADF将会从Web应用的HttpSession中取得WebSession对象,并将之从WebApplication中移除并销毁。
目前为止,只有WebSession的出身不太明白了。还是让我们打开web.xml文件,其中有下面的一段:
这里定义了一个过滤器ADFFilter,每当有用户请求时,请求都会经过ADFFilter过滤,这时,ADFFilter的doFilter(…)方法将会被执行。在这个方法中,ADF会试图获得该请求的HttpSession中保存的WebSession对象,如果这个对象为null,则新建一个WebSession对象并保存(同时保存引用到HttpSession和WebApplication)。
最后,让我们对ADF的工作流程稍作梳理。ADF的工作主要依赖于Web应用的web.xml中配置的ADFServletContextListener监听器和ADFFilter过滤器。当Web应用启动的时候,ADFServletContextListener负责创建WebApplication(老大);当有用户请求的时候,请求会经过ADFFilter过滤并试图获得该请求的WebSession(老大的小弟),如果为null则创建WebSession并保存;在WebSession中包含了该会话使用的所有WebContext(老大的小弟的小弟),有了WebContext,剩下的事情都好办了。
以上是ADF的内部机制,如果理解有困难或者觉得有点麻烦,其实也没必要了解那么清楚,对ADF的几个重要对象的关系有所了解就可以了,下面这个简单的图可能会对你的理解有所帮助。