参数解析器扩展 |
作为示例,这里定义一种伪 JSON 格式,使 iServer 服务器支持该种类型参数的解析。该伪 JSON 格式的使用“(”代替“{”,使用“)”代替“}”,其他定义跟 JSON 格式一致。
第一步,确定自定义的伪 JSON 格式的媒体类型定义为“application/myjson”,媒体类型对应 HTTP 请求的 Content-Type 请求头,供服务器读取从而识别消息体中的参数内容,调用对应的参数解析器进行解析。
第二步,基于 javax.ws.rs.ext.MessageBodyReader,通过@Provider 来标注使用自定义的 MessageBodyProvider,即 FakeJsonDecoder,并使用@Consumes 将媒体类型指定为"application/ myjson";
第三步,判断接收的请求体是否为"application/ myjson"媒体类型;
第四步,读取请求体,并替换伪 JSON 字符串中的"("为"{",")"为"}",即转换为真 JSON 字符串;
第五步,通过 iServer 提供的 JSON 转换器对真 JSON 字符串进行解析,即将字符串转换为 type 类型的 Java 对象,然后返回。
以上过程实现代码如下,代码文件可在%SuperMap iServer_HOME%\samples\code\ExtendExist_JSR\FakeJsonDecoder.java 获取。
package com.supermap.sample.extend;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.Consumes;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import org.json.JSONException;
import com.supermap.services.rest.util.JsonConverter;
//支持这样一种伪 JSON 格式,除"{ }"被“( )”代替外,其他的跟 JSON 一致
@Provider
@Consumes("application/myjson")
public class FakeJsonDecoder implements MessageBodyReader<Object> {
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
// TODO Auto-generated method stub
if (mediaType.equals(new MediaType("application", "myjson"))) {
return true;
}
return false;
}
public Object readFrom(Class<Object> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws java.io.IOException, WebApplicationException {
BufferedReader reader = new BufferedReader(new InputStreamReader(entityStream,"utf-8"));
String data;
StringBuffer buffer = new StringBuffer();
while((data = reader.readLine()) != null) {
buffer.append(data);
}
String text = buffer.toString();
//替换伪 JSON 字符串中的"("为"{",")"为"}",转换为真 JSON 字符串,进行解析
text=text.replace('(', '{');
text=text.replace(')', '}');
try {
//将字符串转换为 type 类型的 Java 对象,然后返回
//iServer 提供的 Json 转换器
JsonConverter converter = new JsonConverter();
return converter.to(text, type);
} catch (JSONException e) {
throw new RuntimeException("请求体内容 不是合法的 myjson 字符串");
}
}
}
模块配置文件的配制方法,如配置文件说明所述,在\ExtendExist_JSR\target\classes\META-INF\extensions\services\rest\SpatialAnalystRest 中添加如下内容:
decoders=com.supermap.sample.extend.FakeJsonDecoder
resourceFiles=MyBufferAnalystRest.xml
将以上代码所在的工程文件 ExtendExist_JSR 编译为 JAR 包(参见:extendexist_jsr.jar),并放在%SuperMap iServer_HOME%\webapps\iserver\WEB-INF\lib 下,即可完成配置。
启动服务,此处以 Geometry 空间分析中的 buffer 分析为例,构建 POST 请求如下:
POST http://supermapiserver:8090/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst/geometry/buffer.xml HTTP/1.1
X-RequestEntity-ContentType: application/myjson
Host: supermapiserver:8090
Content-Length: 223
("analystParameter":("endType":"ROUND", "semicircleLineSegment":4, "leftDistance":("value":1), "rightDistance":("value":1)), "sourceGeometry":("type":"LINE", "points":[("x":23, "y":23), ("x":33, "y":37), ("x":43, "y":23)]))
返回的 xml 表述的请求结果为:
<?xml version="1.0" encoding="utf-8" standalone="no"?><MethodResult>
<isSucceed>true</isSucceed>
<newResourceLocation>http://supermapiserver:8090/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst/geometry/buffer/4</newResourceLocation>
<newResourceID>4</newResourceID>
<postResultType>CreateChild</postResultType>
</MethodResult>