URLhttp://<service-url>/exts/<extensionName>
Parent ResourceMap Service
描述
组织机构通过服务器对象扩展SOE扩展ArcGIS Servera,用Web APIs暴露出他们自定义的GIS功能。ArcGIS的REST API将ArcGIS Server发布的服务暴露给WebAPIs,REST API也可以被扩展用以对自定义的SOE提供相同的支持————将SOE中的功能以资源和操作的形式暴露出来。
对于ArcGIS 10,只有MapService能被SOE扩展,其他服务不可以。
为了从REST中暴露一个SOE,开发者需要实现 IRESTRequestHandler
接口。可以通过Java、C#、C++等多种语言进行实现。实现和注册SOE的详细信息可f分别参见文档ArcGIS Server for Java和ArcGIS Server for .Net,一旦实现并注册了一个服务,就可以在REST API中使用自定义的SOE。该SOE也会出现在服务目录中,用户可以浏览通过SOE暴露出来的资源与操作。
在这篇文档中我们将从REST客户端的视角讨论SOE。我们将讨论三部分的内容:
SOE Schema
SOE Resources
SOE Operations
Schema
EST客户端的一个SOE中的资源和操作的层级结构是基于SOE中指定的Schema的。REST的处理程序调用IRESTRequestHandler 接口中的getSchema()方法得到SOE的 sch ema。这个schema应该以json格式的字符串的形式返回。如果想用REST API获取Schema,那么在SOE根资源上加一个查询参数f=schema即可。
http://<service-url>/exts/<extensionName>?f=schema
看几个schema的例子以帮助理解SOE中资源与操作的层次结构。
Schema1 ————带有一个操作的SOE
{
"operations" : [ "buffer" ]
}
在这个最简单的例子中,这个SOE暴露了唯一的一个操作,从REST API的视角来看,这个SOE暴露了两个Url————根SOE资源以及buffer操作:
http://<service-url>/exts/<extensionName> //根SOE资源
http://<service-url>/exts/<extensionName>/buffer //buffer操作
Shcema2————带有多个操作的SOE
{
"operations" : [ "buffer", "near" ]
}
由于SOE中的operations是一个数组,所以可以指定多个操作。从REST API的视角来看,这个SOE暴露了三个Url————根SOE资源、buffer操作、near操作:
http://<service-url>/exts/<extensionName> //根SOE资源
http://<service-url>/exts/<extensionName>/buffer //buffer操作
http://<service-url>/exts/<extensionName>/near //near操作
Schema3————带有参数的多个操作以及指定的输出格式
{
"operations" : [
{
"name" : "buffer",
"parameters" : ["location", "distance"],
"supportedOutputFormats" : ["json", "amf"]
},
{
"name" : "near",
"parameters" : ["location", "distance", "lookingFor"],
"supportedOutputFormats" : ["json"]
}
]
}
这个Schema暴露了与Schema2中相同的Url。区别是除了指定了操作的名称,还对每个操作指定了与操作相关的其他的参数。这将对用户在服务目录中对每个操作提供更多有用的信息,我们会在下面进行讨论。
Schema4————子资源
{
"name" : "MyMapServiceExtension",
"operations" : ["export", "identify"],
"resources" : [
{
"name" : "metadata"
},
{
"name" : "layers",
"isCollection" : true,
"operations" : ["query"],
"resources" : [
{
"name" : "features",
"isCollection" : true
}
]
}
]
}
除了操作,shcema还可以指定子资源。
这个SOE包含了两个根级别的操作export和identify。它也包含了两个子资源:metadata和layers。metadata资源可以通过如下的Url访问:
http://<service-url>/exts/<extensionName>/metadata
注意layers是一个资源集合(通过将isCollection设置为true进行指定)。这表明存在多个图层资源,每一个layer资源可以通过如下的Url访问:
http://<service-url>/exts/<extensionName>/layers/<layerId>
每一个layer支持一个query操作,Url如下:
http://<service-url>/exts/<extensionName>/layers/<layerId>/query
每一个layer包含一个features资源。因此features也是一个集合资源,每一个feature资源可以通过如下的Url获得:
http://<service-url>/exts/<extensionName>/layers/<layerId>/features/<featureId>
Schema5————只能进行POST的操作
{
"operations" : [
{
"name" : "addStop",
"parameters" : ["location", "name"],
"supportedOutputFormats" : ["json"],
"postOnly" : true
}
]
}
某些操作的类型只能够限于HTTP POST操作。一个方法可以用postOnly标记为只能进行POST操作。我们将在下面进行探讨。
Resources
所有的SOE可能能够支持根资源,如果Schema中指定了子资源(比如Schema4),那么该SOE还会支持子资源。
REST应用程序总是从SOE上请求JSON格式的资源。如果REST客户端用f=json去请求一个资源,那么SOE就会像客户端发送JSON结果。另一方面,服务目录视图中会将SOE发送的JSON格式的数据转换为HTML格式的以便在网页中进行显示。
集合子资源
在Schema4中,layers被指定为根SOE资源的一个集合子资源,我们假设被SOE返回的根资源的JSON如下:
{
"description: "Contitental US",
"extent" : { "xmin" : ..., "ymin" : ..., ...},
"spatialReference" : {...},
...
"layers" : [
{ "id" : 0, "name" : "Cities", ... },
{ "id" : 1, "name" : "Counties", ... },
{ "id" : 2, "name" : "States", ... }
]
...
}
当在服务目录中以HTML显示的时候,REST应用程序会查找到一个layers属性。由于Schema将指定为一个集合子资源,那么它会首先检测这个属性的值是不是一个JSON数组。如果这个数组中的每一个元素都是一个带有id和name属性的JSON对象,那么会用显示一个连接,用name进行显示,用id表示链接的Url。上面的Cities图层的Url如下:
http://<service-url>/exts/<extensionName>/layers/0 //Cities图层
在服务目录中,layers列表显示如下:
用SOE方法获取资源
用REST API获取SOE资源实际上调用了SOE中IRESTRequestHandler
接口的handleRESTRequest
方法。对于资源请求,该方法中的operationName
参数是一个空字符串(”“),然而resourceName
参数是一个相对于根SOE资源的一个字符串。让我们回顾一下Schema4,看一下在请求各种各样的REST资源调用handleRESTRequest方法时,如何将Url转变为resourceName
参数。
Operations
如果SOE Schema指定了支持某些操作的资源,那么这个资源的服务目录页面将会显示这些操作的链接。比如Schema2和Schema3都指定了根SOE资源支持buffer和near操作。因此此资源的服务目录页面将会包含这两个操作的链接,如下图所示:
无参数的操作
在Scehma2中,仅仅指定了操作的的名称,没有提供关于操作的参数的信息以及操作的输出格式。在这种情况下,该操作的服务目录页面提供了一个表单以便用户填写。用户需要同时填写参数名和参数值。例如,Schema2中的buffer的服务目录页面如下图所示:
有参数的操作:
在Schema3中,buffer操作的参数和支持的数据结果都被指定了。在这种情况下,该操作的服务目录页面会显示一个包括参数名和支持的输出格式的表单,如下图所示:
用SOE调用操作
用REST API执行一个SOE的操作会触发SOE中IRESTRequestHandler
接口的handleRESTRequest
的方法。对于操作请求,该方法的operationName
参数是非空的。参数resourceName
还是相对于根SOE资源的一个字符串。让我们回顾一下Schema4,看一下请求各种各样的REST操作调用handleRESTRequest方法时,如何将Url转变为参数resourceName
和参数operationName
,如下所示:
操作参数
REST客户端将操作参数作为请求参数存储于Url(GET方法)或body(POST方法)进行发送。在调用handleRESTRequest
方法之前,REST应用程序强制将输入参数转变为JSON格式对象。请求参数名变为了JSON对象的names。值也被强制转换为合法的JSON格式————数字、bool变量、JSON对象、JSON数组。如果不能够转换为上述的类型,那么就会字符串处理。
用参数f指定输出的格式。
比如,执行Schema3中的near操作
http://<service-url>/exts/<extensionName>/near?
location={x: -117.05, y: 34.11}&distance=2.5&&lookingFor=ATM&f=json
在这个例子中,由于参数location
的值是一个合法的JSON,它将被转换为JSON对象。同样的,参数distance
的值将会转换为数字,参数lookingFor
的值将会转化内字符串。在调用handleRESTRequest
方法的时候,参数operationInput
将会设置成如下的JSON格式的字符串:
{
"location" : {x: -117.05, y: 34.11}, //JSON object
"distance" : 2.5, //number
"lookingFor" : "ATM" //string
}
最后,在调用方法handleRESTRequest
的时侯,参数outputFormat
将会被设置为json(格式参数f的值)。
只能进行POST-only的操作
长时间的改变系统状态的HHTP操作不应该设置成GET。所有的增、删、改都属于这种情况。SOE开发人员应该像Schema5中用postOnly属性将这些操作标记为POST-only。这种情况下,如果REST客户端发送的是非POST请求,那么REST应用程序会强迫禁止调用handleRESTRequest
,一个405的错误会发送到页面。