Extending a Decoder |
As an example, here we define a pseudo JSON format to make SuperMap iServer support the decoding of this type. The pseudo JSON format uses "(" to replace"{", and ")" to replace "}", and other definitions are identical to those of the JSON format.
Firstly, determine the media type of the pseudo JSON format--"application/myjson". The media type corresponds to the Content-Type request header of the HTTP request, which is used for the server to read and identify the parameters in the message body and call the corresponding decoder for decoding;
Secondly, use @Provider to register the customized MessageBodyProvider, namely FakeJsonDecoder, based on avax.ws.rs.ext.MessageBodyReader and use @Produces to specify the media type as "application/mykml";
Thirdly, judges whether or not the received request body is in "application/myjson" media type;
Fourthly, read the request body and replace the "(" and ")" in the pseudo JSON string with "{" and "}" respectively, converting to true JSON string;
Fifthly, decode the true JSON string through the JSON converter provided by SuperMap iServer 6R and get the response.
The code for the above process are as follows, and the code file can be found in %SuperMap iServer Java_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;
// Support the pseudo JSON format, with "{}" being replaced by "()".
@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();
// Replace the "("s and ")"s in the pseudo JSON string with "{"s and "}"s respectively, converting to true JSON, and parse the true JSON string.
text=text.replace('(', '{');
text=text.replace(')', '}');
try {
// Convert the string into Java object and return it.
// The Json converter provided by iServer 6R
JsonConverter converter = new JsonConverter();
return converter.to(text, type);
} catch (JSONException e) {
throw new RuntimeException ("The request body content is not valid myjson string");
}
}
}
Please refer to Configuration Files to learn the configuration method of the module configuration file. Add the content below to [Jar package] \META-INF\extensions\services\restSpatialAnalystRest:
decoders=com.supermap.sample.extend.FakeJsonDecoder
resourceFiles=MyBufferAnalystRest.xml
Complete the configuration by exporting the project ExtendExist_JSR where the code is located into JAR package (see extendexist_jsr.jar) and placing the package in %SuperMap iServer Java_HOME%\webapps\iserver\WEB-INF\lib.
Start the service. Here we take Geometry buffer analysis as an example and construct a POST request as shown below:
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)]))
The response in xml format is as follows:
<?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>