270 lines
9.4 KiB
Markdown
270 lines
9.4 KiB
Markdown
---
|
||
title: GeoServer二次开发-OWS服务(自定义模块)
|
||
date: 2021-04-25
|
||
author: ac
|
||
tags:
|
||
- GeoServer
|
||
categories:
|
||
- GIS
|
||
---
|
||
|
||
本章介绍GeoServer Dispatcher如何在GeoServer中实现OWS服务,以及创建GeoServer 自定义模块的步骤,将其用作GeoServer扩展。
|
||
|
||
<!--more-->
|
||
|
||
## 1. OWS
|
||
|
||
OGC定义了一系列Web协议,这些协议都遵循类似的设计(接口)。将这些共有的接口实现规范和标准参考抽离出来,就形成了OWS。OWS使用以下方法定义服务:
|
||
|
||
- Service
|
||
- Version
|
||
- Request - a service
|
||
|
||
GeoServer的`ows` 包的`org.geoserver.ows.Dispatcher` 类处理所有`OWS`的请求,同时Spring框架会为这些请求注入合适的实现。
|
||
|
||
这些服务使用jar包中包含的Spring applicationContext.xml文件为Dispatcher进行配置。
|
||
|
||
## 2. OWS示例
|
||
|
||
现在我们开始来实现一个简单的OWS服务。
|
||
|
||
1. 新建一个Maven项目
|
||
2. 创建插件(plug-in)
|
||
3. 打包编译
|
||
4. 部署运行
|
||
|
||
### 新建一个Maven项目
|
||
|
||

|
||
|
||
将项目中的Maven指定为本地的安装路径,这样就可以引用之前源码打包的各模块的jar。
|
||
|
||

|
||
|
||
在pom.xml文件中指定父级项目为`org.geoserver.community`、添加依赖以及指定打包方式:
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<groupId>org.geoserver</groupId>
|
||
<artifactId>hello</artifactId>
|
||
<packaging>jar</packaging>
|
||
<version>1.0</version>
|
||
|
||
<properties>
|
||
<maven.compiler.source>8</maven.compiler.source>
|
||
<maven.compiler.target>8</maven.compiler.target>
|
||
</properties>
|
||
|
||
<parent>
|
||
<groupId>org.geoserver</groupId>
|
||
<artifactId>community</artifactId>
|
||
<version>2.18.1</version>
|
||
</parent>
|
||
|
||
<dependencies>
|
||
<dependency>
|
||
<groupId>org.geoserver</groupId>
|
||
<artifactId>gs-main</artifactId>
|
||
<version>2.18.1</version>
|
||
</dependency>
|
||
</dependencies>
|
||
</project>
|
||
```
|
||
|
||
目录结构
|
||
|
||
```yaml
|
||
hello/
|
||
+ pom.xml
|
||
+ src/
|
||
+ main/
|
||
+ java/
|
||
```
|
||
|
||
|
||
|
||
### 创建插件(plug-in)
|
||
|
||
A plug-in is a collection of extensions realized as spring beans.
|
||
|
||
一个插件是通过Spring bean的方式实现的扩展集合。本例创建一个`HelloWorld.java`:
|
||
|
||
```java
|
||
import java.io.IOException;
|
||
import javax.servlet.ServletException;
|
||
import javax.servlet.http.HttpServletRequest;
|
||
import javax.servlet.http.HttpServletResponse;
|
||
|
||
public class HelloWorld {
|
||
|
||
public HelloWorld() {
|
||
// Do nothing
|
||
}
|
||
|
||
public void sayHello(HttpServletRequest request, HttpServletResponse response)
|
||
throws ServletException, IOException {
|
||
response.getOutputStream().write("Hello World".getBytes());
|
||
}
|
||
}
|
||
```
|
||
|
||
该服务相对简单。它提供了一个sayHello方法,接受一个HttpServletRequest和一个HttpServletResponse。这个方法的参数由org.geoserver.ows.Dispatcher自动注入。
|
||
|
||
创建`applicationContext.xml`文件,配置bean:
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||
|
||
<!-- 将新建的HelloWorld服务类配置到Spring容器中 -->
|
||
<bean id="helloService" class="HelloWorld"/>
|
||
|
||
<!-- 在容器中配置一个对应的服务描述类,用于org.geoserver.ows.Dispatcher定位服务 -->
|
||
<bean id="helloService-1.0.0" class="org.geoserver.platform.Service">
|
||
|
||
<!-- 服务的id,对应URL请求中的service名称 -->
|
||
<constructor-arg index="0" value="hello"/>
|
||
|
||
<!-- 服务对应的处理类 -->
|
||
<constructor-arg index="1" ref="helloService"/>
|
||
|
||
<!-- 服务的版本 -->
|
||
<constructor-arg index="2" value="1.0.0"/>
|
||
|
||
<!-- 服务的方法列表 -->
|
||
<constructor-arg index="3">
|
||
<list>
|
||
<value>sayHello</value>
|
||
</list>
|
||
</constructor-arg>
|
||
</bean>
|
||
</beans>
|
||
```
|
||
|
||
上面Spring是根据构造器的方式创建`org.geoserver.platform.Service`的实例bean的,对应的构造方法如下:
|
||
|
||
```java
|
||
public Service(String id, Object service, Version version, List<String> operations) {
|
||
this(id, null, service, version, operations);
|
||
}
|
||
```
|
||
|
||
|
||
|
||
目录结构:
|
||
|
||
```yaml
|
||
hello/
|
||
+ pom.xml
|
||
+ src/
|
||
+ main/
|
||
+ java/
|
||
+ HelloWorld.java
|
||
+ applicationContext.xml
|
||
```
|
||
|
||
|
||
|
||
### 打包编译
|
||
|
||
cmd进入项目根目录下,执行`mvn install`打包项目:
|
||
|
||
```java
|
||
hello>mvn install
|
||
[INFO] Scanning for projects...
|
||
[INFO]
|
||
[INFO] ------------------------< org.geoserver:hello >-------------------------
|
||
[INFO] Building hello 1.0
|
||
[INFO] --------------------------------[ jar ]---------------------------------
|
||
[INFO]
|
||
[INFO] --- git-commit-id-plugin:2.1.15:revision (default) @ hello ---
|
||
[INFO]
|
||
[INFO] --- directory-maven-plugin:0.3.1:highest-basedir (directories) @ hello ---
|
||
[INFO] Highest basedir set to: E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello
|
||
[INFO]
|
||
[INFO] --- fmt-maven-plugin:2.4.0:format (default) @ hello ---
|
||
[debug] Using AOSP style
|
||
[INFO] Processed 1 files (1 reformatted).
|
||
[INFO]
|
||
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello ---
|
||
[INFO] Using 'UTF-8' encoding to copy filtered resources.
|
||
[INFO] Copying 1 resource
|
||
[INFO] Copying 0 resource
|
||
[INFO]
|
||
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ hello ---
|
||
[INFO] Changes detected - recompiling the module!
|
||
[INFO] Compiling 1 source file to E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello\target\classes
|
||
[INFO]
|
||
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hello ---
|
||
[INFO] Using 'UTF-8' encoding to copy filtered resources.
|
||
[INFO] Copying 0 resource
|
||
[INFO] skip non existing resourceDirectory E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello\src\test\resources
|
||
[INFO]
|
||
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ hello ---
|
||
[INFO] Nothing to compile - all classes are up to date
|
||
[INFO]
|
||
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ hello ---
|
||
[INFO]
|
||
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello ---
|
||
[INFO] Building jar: E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello\target\hello-1.0.jar
|
||
[INFO]
|
||
[INFO] --- maven-jar-plugin:2.4:test-jar (default) @ hello ---
|
||
[INFO] Building jar: E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello\target\hello-1.0-tests.jar
|
||
[INFO]
|
||
[INFO] --- maven-source-plugin:2.2.1:jar-no-fork (attach-sources) @ hello ---
|
||
[INFO] Building jar: E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello\target\hello-1.0-sources.jar
|
||
[INFO]
|
||
[INFO] --- maven-source-plugin:2.2.1:test-jar-no-fork (attach-sources) @ hello ---
|
||
[INFO] No sources in project. Archive not created.
|
||
[INFO]
|
||
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hello ---
|
||
[INFO] Installing E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello\target\hello-1.0.jar to C:\Users\P53\.m2\repository\org\geoserver\hello\1.0\hello-1.0.jar
|
||
[INFO] Installing E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello\pom.xml to C:\Users\P53\.m2\repository\org\geoserver\hello\1.0\hello-1.0.pom
|
||
[INFO] Installing E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello\target\hello-1.0-tests.jar to C:\Users\P53\.m2\repository\org\geoserver\hello\1.0\hello-1.0-tests.jar
|
||
[INFO] Installing E:\learning\OGC\geoserverdev\geoserver\geoserver-2.18.1\hello\target\hello-1.0-sources.jar to C:\Users\P53\.m2\repository\org\geoserver\hello\1.0\hello-1.0-sources.jar
|
||
[INFO] ------------------------------------------------------------------------
|
||
[INFO] BUILD SUCCESS
|
||
[INFO] ------------------------------------------------------------------------
|
||
[INFO] Total time: 3.689 s
|
||
[INFO] Finished at: 2021-04-25T14:20:52+08:00
|
||
[INFO] ------------------------------------------------------------------------
|
||
|
||
```
|
||
|
||
<img src="../images/geoserver/image-20210425144736264.png" alt="image-20210425144736264" style="zoom:50%;" />
|
||
|
||
|
||
|
||
### 部署运行
|
||
|
||
将打包好的hello.jar拷贝到GeoServer中的`webapps\geoserver\WEB-INF\lib` 中,重启GeoServer就完成了一个简单的OWS服务扩展。
|
||
|
||
在浏览器端发送请求验证是否部署成功:
|
||
|
||
`http://localhost:8080/geoserver/ows?request=sayHello&service=hello&version=1.0.0`
|
||
|
||

|
||
|
||
回到上面开头说的OWS用来定义服务的方式,在`applicationContext.xml`文件中配置的`org.geoserver.platform.Service`类中定义服务的描述信息:
|
||
|
||
- Service:服务的id
|
||
- Version:服务的版本
|
||
- Requrest:服务操作集合列表中方法名称;
|
||
- Request :在applicationContext.xml中根据构造器引用`org.geoserver.platform.Service`类的第四个集合参数中的方法名称;
|
||
|
||
> 当两个service的id和version都相同时,可以认为这两个service相等。
|
||
|
||
|
||
|
||
## 参考文章
|
||
|
||
[1] Programming Guide https://docs.geoserver.org/latest/en/developer/programming-guide/index.html
|
||
|
||
[2] Implementing a simple OWS service https://docs.geoserver.org/latest/en/developer/programming-guide/ows-services/implementing.html |