参数解析器扩展

发送反馈


实现新的参数解析器 myjson

作为示例,这里定义一种伪 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 字符串");

                }

        }

}

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>