Problems in JSON deserialization using net.sf.json Library

Keywords: JSON Java

Problem description

String content = "{\"response_head\":{\"menuid\":\"xxx\",\"process_code\":\"xxx\",\"verify_code\":\"\",\"resp_time\":\"20150107103234\",\"sequence\":{\"resp_seq\":\"20150107103301\",\"operation_seq\":\"\"},\"retinfo\":{\"retcode\":\"120\",\"rettype\":\"0\",\"retmsg\":\"[182096|]Processing failure,Reason:[Shield specific reasons for failure!]\"}},\"response_body\":{} }";
JSONObject object = JSONObject.fromObject(content);
System.out.println(object.toString());

/*
{"response_head":{"menuid":"xxx","process_code":"xxx","verify_code":"","resp_time":"20150107103234","sequence":{"resp_seq":"20150107103301","operation_seq":""},"retinfo":{"retcode":"120","rettype":"0","retmsg":["182096|"]}},"response_body":{}}
*/

problem analysis

Using json-lib-2.4-jdk15.jar, test code as above, you will find that the value of retmsg becomes "[182096 |".

The test simplifies the json string and the final effect is as follows:

Examples of parsing failures:

"{" response_head ":{" retmsg ":" [182096 ]] Failure to process, reason: [Shield specific failure reasons! ____________ []

If we continue to simplify, we will succeed in parsing.

"{" response_head":" [182096 |] Failure to process, reason: [Shield specific failure reasons! _____________ }

Looking for the source code, we found that json-lib would try to parse the string to see if it was a JSON object in some cases. (Nima, too smart)

260 lines in AbstractJSON.java, where str is later.

         } else if( JSONUtils.mayBeJSON( str ) ) {
            try {
               return JSONSerializer.toJSON( str, jsonConfig );
            } catch( JSONException jsone ) {
               return str;
            }
         }

Line 1130 in JsonArray.java, where v is already "182096 |". At this point, we will judge whether v is a json object. If we make an array to go back, otherwise we will make a string (the above phenomenon).

               tokener.back();
               Object v = tokener.nextValue( jsonConfig );
               if( !JSONUtils.isFunctionHeader( v ) ){
                  if( v instanceof String && JSONUtils.mayBeJSON( (String) v ) ){
                     jsonArray.addValue( JSONUtils.DOUBLE_QUOTE + v + JSONUtils.DOUBLE_QUOTE,
                           jsonConfig );
                  }else{
                     jsonArray.addValue( v, jsonConfig );
                  }
                  fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig );
               }

For example, the following situation produces an array:

"{" response_head ":{" retmsg ":" [{1820:96}] processing failure, reason: [shield specific failure reasons! []

{"response_head":{"retmsg":[{"1820":"96|"}]}}

As for how to judge whether it is json or not, it will be judged that it ends [at the beginning, at the end]. It happens to be shot. When trying to intercept the intermediate content, it happens to encounter the middle character, so the generated string is truncated part.

   /**
    * Tests if the String possibly represents a valid JSON String.<br>
    * Valid JSON strings are:
    * <ul>
    * <li>"null"</li>
    * <li>starts with "[" and ends with "]"</li>
    * <li>starts with "{" and ends with "}"</li>
    * </ul>
    */
   public static boolean mayBeJSON( String string ) {
      return string != null
            && ("null".equals( string )
                  || (string.startsWith( "[" ) && string.endsWith( "]" )) || (string.startsWith( "{" ) && string.endsWith( "}" )));
   }

Problem conclusion

  • When a value in a json object ends with "{"beginning,"}" or "["beginning,"]", the parsing result may not be expected.
  • Unfortunately, for now, this problem is not solved. Consider using other json libraries.

Posted by Beyond Reality on Thu, 28 Mar 2019 11:03:29 -0700