赞
踩
拿到源码后,看着一堆代码看着可头疼,不知道其其使用框架,也不知道其中的调用关系是怎么样的,经过分析后可以看到其框架结构如下
主体框架 | spring(不是spring boot) |
UI框架 | Wicket(类似jsp) |
通信框架(前后台交互) | Servlet |
地理处理框架 | GeoTools |
模板框架 | FreeMarker |
从上图可以看出index.html是个空页面,而且被重定向到“web/”。很显然src/web/app/src/main/webapp路径下没有web的文件夹,那么就能猜出来地址肯定又被哪个地方拦截了,然后就能想到servlet的Mapping 和 Filter
由前言中的框架结构得知,geoserver的前后端交互是由Servlet完成的,关于Servlet,我找到一篇相对来说写的还算不错的文章==>文章,不了解的可以看一下。而Servlet的配置文件在
src/web/app/src/main/webapp/WEB-INF/web.xml
如果从前后端交互的角度来看的话这个配置文件就是项目的主入口了,可以从浏览器的请求路径中一步步的去调试代码了(实际上情况可能会稍微复杂一点儿,后面会讲到)
在配置文件中看到诡异的一点是,只有Servlet的过滤器链的配置,而没有具体接口的配置,熟悉前端的人第一想法应该是想找到路由,然后一步步分析其中的逻辑关系,但是这个配置里面没有,只是指出了过滤器,不过这也没关系,后台和前端思路总是不一样的嘛。转念一想,主体框架里面还有个spring,它不就是一个大管家嘛,前后端的请求类都归它管,不过这个先不管他,后面再介绍。
过滤器可以拦截前后端请求,做一些安全验证或者日志之类的操作。在配置文件中可以看到这样一些过滤器
- <filter>
- <filter-name>FlushSafeFilter</filter-name>
- <filter-class>org.geoserver.filters.FlushSafeFilter</filter-class>
- </filter>
- <filter>
- <filter-name>SessionDebugger</filter-name>
- <filter-class>org.geoserver.filters.SessionDebugFilter</filter-class>
- </filter>
- <filter>
- <filter-name>GZIP Compression Filter</filter-name>
- <filter-class>org.geoserver.filters.GZIPFilter</filter-class>
- <init-param>
- <param-name>compressed-types</param-name>
- <param-value>text/.*,.*xml.*,application/json,application/x-javascript</param-value>
- </init-param>
- </filter>

在 Java 的 Servlet 技术中,Filter
是一个可以拦截、处理请求和响应的对象。FlushSafeFilter
通过拦截请求和响应,确保在数据传输过程中,如果发生了缓冲区刷新操作,数据不会丢失,从而保证了数据传输的完整性和安全性。
SessionDebugFilter
是 GeoServer 中的一个过滤器,其主要作用是监控和记录 HTTP 会话(session)的创建,以便于调试和诊断。这个过滤器的目的是帮助开发者发现和解决在 Web 应用程序中不应该创建会话的情况,特别是在那些本应无状态的场景下,例如 OGC(Open Geospatial Consortium)和 REST 服务。
。。。。。。
上面有讲到在servlet中没有路由的配置,猜想到了spring,找度娘询问得知:在 Spring MVC 应用程序中,可以在<bean>
中配置和使用 <servlet-mapping>,于是乎找到了如下代码
src/web/app/src/main/webapp/WEB-INF/web.xml
- <!-- spring dispatcher servlet, dispatches all incoming requests -->
- <servlet>
- <servlet-name>dispatcher</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- </servlet>
-
- <!-- single mapping to spring, this only works properly if the advanced dispatch filter is
- active -->
- <servlet-mapping>
- <servlet-name>dispatcher</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
src/web/core/src/main/java/applicationContext.xml
-
- <bean id="webApplication" class="org.geoserver.web.GeoServerApplication">
- </bean>
-
- <bean id="wicket"
- class="org.springframework.web.servlet.mvc.ServletWrappingController"
- lazy-init="true" depends-on="webApplication">
- <property name="servletClass">
- <value>org.geoserver.web.GeoServerWicketServlet</value>
- </property>
- <property name="servletName">
- <value>wicket</value>
- </property>
- <property name="initParameters">
- <props>
- <!-- either development on deployment, make sure you set it to deployment
- before releasing! -->
- <prop key="configuration">development</prop>
- </props>
- </property>
- </bean>
-
- <bean id="webDispatcherMapping"
- class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"
- lazy-init="true">
- <property name="alwaysUseFullPath" value="true" />
- <property name="mappings">
- <props>
- <prop key="/web">#{webDispatcherMappingSystem}</prop>
- <prop key="/web/**">#{webDispatcherMappingSystem}</prop>
- <prop key="/web/resources/**">#{webDispatcherMappingSystem}</prop>
- <prop key="/">filePublisher</prop>
- <prop key="/index.html">filePublisher</prop>
- </props>
- </property>
- </bean>

由上面代码可以看出来当访问的地址为/web时,实际上访问的是 webDispatcherMappingSystem,而webDispatcherMappingSystem就是wicket,而wicket继承了webApplication,也就是说当访问/web时实际上访问的是一个org.apache.wicket.protocol.http.WebApplication,那么从geoserver的主体代码角度来说 org/geoserver/web/GeoServerApplication.java是程序的主入口
从Servlet的配置文件中找到了程序的代码主入口,还需要找到具体页面显示什么东西的主入口,在src/web/core/src/main/java/org/geoserver/web/GeoServerApplication.java文件中找到了如下代码
- /** The {@link GeoServerHomePage}. 主页 */
- @Override
- public Class<GeoServerHomePage> getHomePage() {
- return GeoServerHomePage.class;
- }
由此可见主入口终于找到了,是个wicket(项目的UI框架)界面,具体用法可以百度,此处就不多赘述了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。