GeoServer学习手记(十):一个完整的WMS请求响应过程

 

GeoServer学习手记(十):一个完整的WMS请求响应过程

粟卫民http://www.gisdev.cn/ http://blog.csdn.net/suen/ 日期:2009-12-23

保留所有版权。如需转载,请联系作者,并在醒目位置注明出处

前面对ServletHTTP派发过程进行了介绍:

GeoServer学习手记(四):ServletHTTP派发过程之一:

http://blog.csdn.net/suen/archive/2009/11/02/4759332.aspx

GeoServer学习手记(五):ServletHTTP派发过程之二:

http://blog.csdn.net/suen/archive/2009/11/02/4759398.aspx

GeoServer学习手记(六):ServletHTTP派发过程之三:

http://blog.csdn.net/suen/archive/2009/11/02/4759410.aspx

GeoServer学习手记(七):ServletHTTP派发过程之四:

http://blog.csdn.net/suen/archive/2009/11/11/4799572.aspx

GeoServer学习手记(八):ServletHTTP派发过程之五:

http://blog.csdn.net/suen/archive/2009/11/11/4799587.aspx

也分析了WMS工程的包:

http://blog.csdn.net/suen/archive/2009/11/13/4808860.aspx

接下来以一个完整的WMS访问过程来分析WMS工程中代码执行的过程。

一、HTTP GET请求

WMS的请求一般使用HTTP Get的形式直接从地址栏输入或者通过JS代码发送到服务器端。请求的格式如下所示:

http://localhost:8080/geoserver /wms?bbox=-74.01199448397661,40.70732689845813,-74.00841053684495,40.71216558957052&styles=&Format=application/openlayers&request=GetMap&version=1.1.1&layers=tiger:poi&width=457&height=550&srs=EPSG:4326,该请求中wms是要请求的服务,version=1.1.1是请求的wms版本,GetMap是请求的服务方法,tiger:poi是要访问的地理数据。

 

二、HTTP 派发

GeoServerMVC架构是建立在SpringWeb MVC的基础之上的。Spring Web MVC的核心控制类是org.springframework.web.servlet.DispatcherServletHTTP请求一般都先发送给这个Servlet,做一些HTTP请求的通用处理(比如文件上载)后,通过合适的派发机制转发给不同的Spring容器中的Bean,也就是不同业务逻辑、服务处理的控制器(Logic Control),由这些控制器结合不同模型(Model),如空间数据模型、属性数据模型、地图样式模型等,进行处理,形成结果模型,并经 DispatcherServlet返回客户端。

org.springframework.web.servlet.DispatcherServlet相关配置位于GeoServerWeb工程的配置文件web.xml中。

   1Servlet声明

    <servlet>

        <servlet-name>dispatcher</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  

    </servlet>

    2URL Mapping

    <servlet-mapping>

        <servlet-name>dispatcher</servlet-name>

        <url-pattern>/wms/*</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

        <servlet-name>dispatcher</servlet-name>

        <url-pattern>/wcs/*</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

        <servlet-name>dispatcher</servlet-name>

        <url-pattern>/wfs/*</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

        <servlet-name>dispatcher</servlet-name>

        <url-pattern>/ows/*</url-pattern>

</servlet-mapping>

这说明,对于/wms/*/wcs/*/wfs/*/ows/*等地址的请求,都会调用org.springframework.web.servlet.DispatcherServlet对象来响应。

 

三、org.springframework.web.servlet.DispatcherServlet派发流程

Spring框架下,org.springframework.web.servlet.DispatcherServlet基于每个工程的applicationContext.xml的配置,将请求转发给专门的对象处理。其中,根据wms工程的配置,wmsputstyles路径下的请求,都由dispatcher处理。

    <!-- http url mapping -->

    <bean id="wmsURLMapping"

       class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

       <property name="alwaysUseFullPath" value="true"/>

       <property name="mappings">

           <props>

              <prop key="/wms">dispatcher</prop>

              <prop key="/wms/putstyles">putStylesWrapper</prop>

              <prop key="/wms/*">dispatcher</prop>

           </props>

       </property>

    </bean>

关于dispatcher对象的配置在main工程的applicationContext.xml,处理对象的类是org.geoserver.ows.Dispatcher

    <!--  dispatcher -->

    <bean id="dispatcher" class="org.geoserver.ows.Dispatcher">

      <!--

        See the applicationSecurityContext document. You can safely remove this

        if in need for playing with a non secure version of Geoserver

       -->

      <property name="securityInterceptor">

        <ref bean="operationSecurityInterceptor"/>

      </property>

</bean>

org.geoserver.ows.Dispatcher继承自spring框架的AbstractController类。它对于HTTP请求的处理是在handleRequestInternal(HttpServletRequest httpRequest, HttpServletResponse httpResponse)中处理。此函数再调用本身的execute(Request req, Operation opDescriptor),先分析出请求的服务(Service)、版本(Version)、操作(Operation),然后根据配置信息与GeoServerExtensions匹配找到服务处理的Beanwms的配置信息如下所示。

    <!-- wms service + descriptor -->

    <bean id="wmsService2" class="org.geoserver.wms.DefaultWebMapService">

      <constructor-arg ref="wms"/>

    </bean>

    <alias name="wmsService2" alias="webMapService"/>

   

    <bean id="wmsServiceDescriptor" class="org.geoserver.platform.Service">

       <constructor-arg index="0" value="wms"/>

       <constructor-arg index="1" ref="wmsService2"/>

       <constructor-arg index="2" value="1.1.1"/>

    </bean>

此配置信息说明对于服务IDwms的操作,由org.geoserver.wms.DefaultWebMapService来使用与操作同名的函数来处理。

这样,对于下面的请求:

http://localhost:8080/geoserver /wms?bbox=-74.01199448397661,40.70732689845813,-74.00841053684495,40.71216558957052&styles=&Format=application/openlayers&request=GetMap&version=1.1.1&layers=tiger:poi&width=457&height=550&srs=EPSG:4326

将由org.geoserver.wms.DefaultWebMapServicegetMap函数来处理。

四、org.geoserver.wms.DefaultWebMapServicegetMap函数处理过程

此函数先根据配置信息得到wmsGetMap对象,所属类是org.vfny.geoserver.wms.servlets.GetMap

    <bean id="wmsGetMap"

       class="org.vfny.geoserver.wms.servlets.GetMap"

       parent="wmsService">

    </bean>   

然后执行此对象的getResponse()方法。然后创建一个GetMapResponse对象。

五、写输出

写输出是通过执行org.geoserver.ows.Dispatchervoid response(Object result, Request req, Operation opDescriptor)函数。此函数先循环搜索和排序响应类集合responsesList responses = GeoServerExtensions.extensions(Response.class);),确定响应类response Response response = (Response) responses.get(0);),再根据输出策略outputStrategyServiceStrategy outputStrategy = findOutputStrategy(req.httpResponse);)进行输出。

具体执行在set the mime type时(req.httpResponse.setContentType(response.getMimeType(result, opDescriptor));)调用ResponseAdaptergetMimeType(Object value, Operation operation)函数,此函数再调用delegate.execute(request)来执行(delegate即第四步创建的GetMapResponse对象)。最终的执行在GetMapResponse对象的execute(Request req)函数。

 

 

猜你喜欢

转载自blog.csdn.net/suen/article/details/5063365