扩展一个iServer REST资源(Restlet机制)的简单模板工程

作者:MR

    上一篇博客SuperMap iServer REST资源(Restlet)扩展机制简介我们对iServer资源扩展有了些了解,现在给大家提供一个简单的模板工程,方便大家入门。
    就不截图工程创建过程了,直接说下步骤,最下方提供工程下载。
    本工程扩展一个com.supermap.services.rest.resources.AlgorithmResultSetResource类的资源,使用jdk1.8(iServer8.1.0及以上正常运行的JVM版本)编译。看过上一篇并使用过iServer的朋友就会知道这个资源就是地图服务的queryResults数据服务的featureResults等资源的父类,扩展这个资源能够实现比较复杂的操作,支持GET、POST、HEAD等HTTP方法,现在介绍下具体怎么扩展。

    首先,你需要一份帮助文档,嗯,是两份帮助文档,一份iServer8C的(8.1.1在线帮助地址、chm在资源中心网站 下载,或者在你使用的iServer的docs目录下(非deploy包)也能找到这俩),一份iServer 6R的(6R的帮助文档百度盘:链接:http://pan.baidu.com/s/1c2KhPhY 密码:kfsx)。资源类在iServer6R的帮助文档里找到目录-API参考-javadoc(按资源类的包名目录结构去找)。


    扩展这个资源的步骤

1、创建一个java工程,这里取名MyFirstExtent

2、 添加引用,为省心,可以把%SuperMap iServer_HOME%/webapps/iserver/WEB-INF/lib目录下所有jar包都引用

3、 创建包和class,这里创建com.supermap.services.rest.resources.impl(iServer自己的资源实现类也在这个包名下)包和ExportParams类,ExportParams类继承AlgorithmResultSetResource类并实现其抽象方法。

4、 实现业务逻辑,这里就只是简单返回你的请求体

5、配置资源

6、导出工程为jar包,放到%SuperMap iServer_HOME%/webapps/iserver/WEB-INF/lib 目录下,重启iServer,测试扩展的资源可用性

    下面直接从第四步实现业务逻辑开始

###实现业务逻辑
    没什么好说的逻辑,上代码

package com.supermap.services.rest.resources.impl;

import java.util.HashMap;
import java.util.Map;

import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;

import com.supermap.services.rest.resources.AlgorithmResultSetResource;

public class ExportParams extends AlgorithmResultSetResource
{

	public ExportParams( Context context, Request request, Response response )
	{
		super( context, request, response );
		// 添加支持的请求方法,AlgorithmResultSetResource默认只支持POST请求
		// ArrayList< String > localArrayList = new ArrayList<>( );
		// localArrayList.add( "GET" );
		// this.addSupportedOperations( localArrayList );
	}

	/*
	 * 创建请求体对象
	 */
	@ SuppressWarnings( "rawtypes" )
	@ Override
	public Map< String, Class > createArithParamClassMappings( )
	{
		Map< String, Class > params = new HashMap<>( );
		params.put( "params", String.class );
		return params;
	}

	/*
	 * 判断资源是否存在
	 */
	@ Override
	public boolean isResourceExist( )
	{
		return true;
	}

	/*
	 * 资源ID
	 */
	@ Override
	protected String getArithName( )
	{
		return "ExportParams";
	}

	/*
	 * 检查请求体,不符合要求抛出异常,比如检查类型和必填参数
	 */
	@ Override
	public final void checkRequestEntityObjectValid( Object obj )
	{
	}

	/*
	 * 业务逻辑入口,arg0为获取到的请求体,返回值既是客户端得到的返回
	 */
	@ Override
	public Object runArithmetic( @ SuppressWarnings( "rawtypes" ) Map arg0 )
	{
		return arg0;
	}
}

    以上就是扩展一个AlgorithmResultSetResource资源需要的最少代码。

###配置资源
    该资源可以配置到数据服务模块或者地图服务模块,具体实现业务逻辑时自行选择,主要看相应的服务组件提供的方法是否满足业务需求,这里没有使用任何服务组件,所以两个地方都可以配置,资源配置说明参考上一篇或帮助文档

步骤:

  1. 工程里创建资源文件夹(source folder)比如:resources
  2. resources文件夹下创建META-INF/extensions/services/rest文件夹(4个文件夹)
  3. META-INF/extensions/services/rest文件夹下创建并编辑两个个无后缀的文件(这里的资源两个模块都用):mapRest、dataRest
  4. resources文件夹下创建并编辑两个xml文件,命名MyDataExtent.xml、MyMapExtent.xml(可以合用一个,这里为了方便大家拷贝)

其中,mapRest文件的内容:

filters=
verifiers=
resourceFiles=MyMapExtent.xml

dataRest文件的内容:

filters=
verifiers=
resourceFiles=MyDataExtent.xml

resourceFiles指定的资源配置文件路径是相对于导出的jar包根目录的,导出jar包后可自己用压缩软件打开jar包查看目录结构。

资源xml文件的配置可以参考上一篇或者帮助文档
其中,MyMapExtent.xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
  <resource>
    <configID>ExportParams</configID>
    <!-- /maps/{mapName}/ExportParams 表示放到具体某个地图下,这样可以在资源逻辑实现里通过url参数拿到地图名-->
     <urlTemplate>/maps/{mapName}/ExportParams;/maps/{mapName}/exportparams</urlTemplate>
     <resourceType>ArithResultSetResource</resourceType>
    <implementClass>com.supermap.services.rest.resources.impl.ExportParams</implementClass>
    <extensionEncoderBeanNames></extensionEncoderBeanNames>
    <extensionDecoderBeanNames></extensionDecoderBeanNames>
    <extensionHttpActionHandlerBeanName></extensionHttpActionHandlerBeanName>
  </resource>
</resources>

MyDataExtent.xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
  <resource>
    <configID>ExportParams</configID>
    <!-- 分号分割,表示这些url都能访问到本资源 -->
     <urlTemplate>/data/ExportParams;/data/exportparams</urlTemplate>
     <resourceType>ArithResultSetResource</resourceType>
    <implementClass>com.supermap.services.rest.resources.impl.ExportParams</implementClass>
    <extensionEncoderBeanNames></extensionEncoderBeanNames>
    <extensionDecoderBeanNames></extensionDecoderBeanNames>
    <extensionHttpActionHandlerBeanName></extensionHttpActionHandlerBeanName>
  </resource>
</resources>

###导出jar包放到iServer的效果
data
图一↑
data2
图二↑
map
图三↑
验证
图四↑

说明:到这一步已经完成该资源的扩展,图一、图三代表资源的配置文件生效;图二说明资源不支持GET请求;图四表示通过请求验证,返回结果符合预期。

另:图四中的url解读

/ExportParams.json:表示使用JSON格式表述(请求和直接返回的结果都使用JSON格式),不写则默认使用html表述,也就是浏览器访问url时(GET请求)显示的html页面。
?returnContent=true:url参数是returnContent,参数的值是true,默认false。true:直接返回结果,也就是资源runArithmetic方法的返回值经过对应表述生成器(Encoder)处理后的结果。false:不直接返回结果,创建子资源(临时资源存储,可以查看iServer帮助文档配置),返回临时资源ID和uri,iServer的其他同类资源均支持这种方式,现在我们扩展的资源还不支持这种方式,要支持需要扩展一个com.supermap.services.rest.resources.AlgorithmResultResource资源类。

###本资源的扩展机制和HTTP请求过程
    上一篇已经有过说明,看了本篇之后应该会加深了解,这里再复述一下,先简单用我的方式说明下整个HTTP请求过程:

  1. 客户端发送HTTP请求,通过安全验证后iServer找到服务接口配置的HTTP 请求处理器处理该请求
  2. HTTP 请求处理器通过url模板找到对应资源,调用资源isResourceExist判断资源是否存在,找不到对应资源等情况会抛出与请求URL模板不匹配,资源不存在等异常、返回网络请求404等状态,输出到日志(可能,根据日志的输出级别)和返回给客户端
  3. HTTP 请求处理器获取资源参数映射的Map对象,通过URL参数获取到请求的表述格式,比如.JSON
  4. HTTP 请求处理器找到对应参数解析器(Decoder),将请求体转换成资源参数映射的Map对象
  5. HTTP 请求处理器调用资源运行算法方法,根据url参数returnContent决定将算法返回结果通过对应表述生成器(Encoder)返回给客户端还是创建对应的算法结果子资源

可以通过扩展一个HTTP处理器(帮助文档示例点我)或者反编译现有HTTP处理器来进一步了解这个过程。

    本例涉及部分重写的方法在这个过程中扮演的角色:

getArithName:返回值即是资源的ID,配置资源、html表述的模板文件名、iServer管理页列出的资源名等使用的标识就是它的返回值。
createArithParamClassMappings:创建参数映射,即客户端HTTP请求的请求体的类型
runArithmetic:顾名思义,就是运行你自定义算法的入口,它的参数就是经由参数解析器(Decoder)处理后的结果,它的返回值会交给表述生成器(Encoder)处理

####其他

    调试环境配置请参考iServer帮助文档:开始 > iServer 开发与扩展指南 > Java 远程调试技术

    若要支持子资源com.supermap.services.rest.resources.AlgorithmResultResource),还需要重写AlgorithmResultSetResourcegetResourceContent方法,具体实现请参考工程源码。

    请求体的设计,前面已经说过,你的请求体,比如json,应该是createArithParamClassMappings方法返回的Map对象(本例:Map< String, String.class >)表示的对象,比如本例中是{“params”:“字符串”}。请求体的设计要满足JSON标准格式,比如,不能出现二维数组等。具体请求体是否合法,有一个方式去验证,iServer JSON Decoder和Encoder都使用com.alibaba.fastjson.JSON静态类去处理,可以先用它去验证下,你设计的请求体能否转换成你需要的对象,示例代码:

//com.alibaba.fastjson.JSON.parseObject(String text, Class<T> clazz)
InputFormat Input=JSON.parseObject( inputJSON, InputFormat.class );

    到这里就全部结束了,欢迎传播和围观,页底给出本工程的源码及编译后的jar包。最终的工程在上面的基础上增加了结果资源的实现和支持GET请求以及html表述。

下载链接:http://download.csdn.net/detail/supermapsupport/9797554

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值