7.4 JSON Support

The Limax provides the complete JSON support (the Java, C#, C++ and Lua versions all provide the JSON support which is consistent with the Javascript, and maximumly ensure the usage is the same with Javascript), to communicate with the other json supported third party system.


  • 7.4.6 Advanced function

    • Non-standard JSON string (Java, C#, C++, Lua)

      Some out-of-date system's encoders use the equal mark in place of the colon of the JSON/Object string description, and semicolon in place of the comma to split the JSON element. The decoder can tolerate this input. In addition, the true, false and null three JSON elements are processed as case-insensitive by the decoder.


    • Encoding stream (Java, C#)


      	public static void encode(Object obj, Appendable a);
      

      The JSONEncoder provides the above method, which allows the encoder to cooperate with the other stream processing module of the limax.codec and directly output to the target.


      	OutputStream os = ...;
      	JSONEncoder.encode(json, new CharSource(StandardCharsets.UTF_8, new SinkStream(os)));
      

      For example, the above code encodes the json object encoded result which is handled as a character stream source to the byte stream through the UTF8 encoder, and then sends to the output stream.

      This process need to catch the exception. All exception during the stream processing will be finally wrapped to the JSONException, then thrown.


    • Stream decoding (Java, C#, C++)

      The Java, C# and C++ three versions decode via stream, input the character stream not the simple string.

      The JSONDecoder gets the character input via void accept(char c) method, and this method might throw the exception. The C++ version throws the JSONException, the Java version throws the RuntimeException, and the C# version throws the Exception.

      2. The decoding object constructed via JSONDecoder() method only decodes a JSON component, and get the JSON object via JSON get() method after the decoding finishes.

      3. The JSONDecoder(JSONConsumer consumer) method allows a consumer provided to get the decoded object (continuously decode the JSON component).

      4. The JSONDecoder of the Java and C# version implements the limax.codec.CharConsumer interface, and allows to cooperate with the other stream module of the limax.codec.


      Example 1 (The decoding method of the Endpoint.java comes from the service configuration information of the Auany)

      Endpoint.java


      public static List<ServiceInfo> loadServiceInfos(String httpHost, int httpPort, int appid, long timeout,	int maxsize, File cacheDir, boolean staleEnable) throws Exception {
      	JSONDecoder decoder = new JSONDecoder();
      	new HttpClient("http://" + httpHost + ":" + httpPort + "/app?native=" + appid, timeout, maxsize, cacheDir,staleEnable).transfer(new CharSink(decoder));
      	List<ServiceInfo> services = new ArrayList<ServiceInfo>();
      	for (JSON json : decoder.get().get("services").toArray())
      		services.add(new ServiceInfo(appid, json));
      	return services;
      }
      

      Here, the HttpClient downloads the content of the specified URL, adapts via the CharSink, sends the byte stream to the decoder, then execute the get() operation on the decoder to obtain the JSON object. When the decoder is wrapped by adapter, only the outermost layer need to be considered when handling the exception, and here is the IOException thrown by the HttpClient.transfer. The next JSON accessing might throw the JSONException. The whole method processes simply and throws Exception.


      Example 2 (The multi JSON decoding implemented with the C++)


      JSONDecoder jd([](std::shared_ptr<JSON> json) {printf("%s\n", json->toString().c_str()); });
      for (auto c : std::string("{\"a\":10}[2,3]5[12]"))
      	jd.accept(c);
      

      The below four lines are ouput by this example:

      <Object>

      <Array>

      5

      <Array>

      The output result just reflects the structure of the JSON input string. It should be noted that if appending a number in the end of this string, the output result is still the above four lines. In the stream mode, the decoding of the digit is special. Without referencing to the next character, it is impossible to determine whether this digit is end, unlike the string using the double quotes as the end. So the decoding code implemented with the JSONDecoder by the JSON.parse will call the internal flush method of the JSONDecoder in the end. The flush simply accept a space. The JSON specification defines that the whitespace between the JSON components is ignored, so appending a space resolves the digital issue. Moreover, it should be noted that the JSON.parse only decodes a JSON component. If the string of the above code is used to call the JSON.parse, the decoder throws the exception when suffering the first non-whitespace which is the next "[" after it completes the "{\"a\":10}". Using the Javascript and Lua versions to execute this parse has the same effect. The semanteme of each language version is consistent.


Prev Next