GeoServer学习手记(十):一个完整的WMS请求响应过程
目录
GeoServer学习手记(十):一个完整的WMS请求响应过程
粟卫民http://www.gisdev.cn/ http://blog.csdn.net/suen/ 日期:2009-12-23
保留所有版权。如需转载,请联系作者,并在醒目位置注明出处
前面对Servlet及HTTP派发过程进行了介绍:
GeoServer学习手记(四):Servlet及HTTP派发过程之一:
http://blog.csdn.net/suen/archive/2009/11/02/4759332.aspx
GeoServer学习手记(五):Servlet及HTTP派发过程之二:
http://blog.csdn.net/suen/archive/2009/11/02/4759398.aspx
GeoServer学习手记(六):Servlet及HTTP派发过程之三:
http://blog.csdn.net/suen/archive/2009/11/02/4759410.aspx
GeoServer学习手记(七):Servlet及HTTP派发过程之四:
http://blog.csdn.net/suen/archive/2009/11/11/4799572.aspx
GeoServer学习手记(八):Servlet及HTTP派发过程之五:
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 派发
GeoServer的MVC架构是建立在Spring的Web MVC的基础之上的。Spring Web MVC的核心控制类是org.springframework.web.servlet.DispatcherServlet。HTTP请求一般都先发送给这个Servlet,做一些HTTP请求的通用处理(比如文件上载)后,通过合适的派发机制转发给不同的Spring容器中的Bean,也就是不同业务逻辑、服务处理的控制器(Logic Control),由这些控制器结合不同模型(Model),如空间数据模型、属性数据模型、地图样式模型等,进行处理,形成结果模型,并经 DispatcherServlet返回客户端。
org.springframework.web.servlet.DispatcherServlet相关配置位于GeoServer的Web工程的配置文件web.xml中。
1、Servlet声明
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
2、URL 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工程的配置,wms除putstyles路径下的请求,都由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匹配找到服务处理的Bean,wms的配置信息如下所示。
<!– 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>
此配置信息说明对于服务ID为wms的操作,由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.DefaultWebMapService的getMap函数来处理。
四、org.geoserver.wms.DefaultWebMapService的getMap函数处理过程
此函数先根据配置信息得到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.Dispatcher的void response(Object result, Request req, Operation opDescriptor)函数。此函数先循环搜索和排序响应类集合responses(List responses = GeoServerExtensions.extensions(Response.class);),确定响应类response (Response response = (Response) responses.get(0);),再根据输出策略outputStrategy(ServiceStrategy outputStrategy = findOutputStrategy(req.httpResponse);)进行输出。
具体执行在set the mime type时(req.httpResponse.setContentType(response.getMimeType(result, opDescriptor));)调用ResponseAdapter的getMimeType(Object value, Operation operation)函数,此函数再调用delegate.execute(request)来执行(delegate即第四步创建的GetMapResponse对象)。最终的执行在GetMapResponse对象的execute(Request req)函数。
转载自:https://blog.csdn.net/suen/article/details/5063365