Author Message
MichaelDailous_deprecated
Joined: Nov 11, 2013
Messages: 171
Offline
I've encountered a problem where the REST method MessageBody doesn't seem to accept a JSON array as the object to encode.

I've tested the REST service using an external tester with the following valid JSON array syntax:

[

{
"Field1":"Value",
"Field2":"Value"
},
{
"Field1":"Value",
"Field2":"Value"
}
]


and the web service correctly extracts and build the necessary objects.

If I try to add the following code to the REST MessageBody field in OD 7.1 as syntax:

JSON [

{
"Field1":"Value",
"Field2":"Value"
},
{
"Field1":"Value",
"Field2":"Value"
}
]


The first open bracket is removed completely, but the close bracket at the end remains.

If I try to add the following code to the REST MessageBody field in OD 7.1 as syntax:

JSON {

[
{
"Field1":"Value",
"Field2":"Value"
},
{
"Field1":"Value",
"Field2":"Value"
}
]
}


The JSON isn't properly formatted and an exception is thrown. I've even tried overriding the setMessageBody(...) method as described in other posts, but to no avail.

How can I have my MessageBody accept a JSON formatted array?

Thanks in advance,
Michael
WilsonYu
Joined: Nov 6, 2013
Messages: 3950
Offline
I don't think the format in which you use array is correct. Take a look at some examples here:

http://www.w3schools.com/js/js_json_arrays.asp

WilsonYu
Joined: Nov 6, 2013
Messages: 3950
Offline
try this:

JSON {"elements":
[
{
"Field1":"Value",
"Field2":"Value"
},
{
"Field1":"Value",
"Field2":"Value"
}
]
}
MichaelDailous_deprecated
Joined: Nov 11, 2013
Messages: 171
Offline
The JSON array is an array of objects, not simple data types. The format is correct. Adding the "elements" as a key doesn't work as the web service endpoint is expecting an array of objects, not a wrapper that contains an array of objects. The specific error returned when the JSON is converted is:

{"Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[UnisysNG.Logging.Models.LogAttribute]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T> ) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\r\nPath 'elements', line 1, position 12."}


If I manually execute the web service using a REST testing tool, with the format above that works (the first format), the object is deserialized correctly.

It appears the OD REST interface doesn't allow the transmission of JSON arrays unless they're wrapped in another object. Is this correct?

Michael
WilsonYu
Joined: Nov 6, 2013
Messages: 3950
Offline
OD automatically takes the string and start with the first "{". The string below (you have) is not a validate JSON object string. You just need to verify it using some on-line tool. You would need a key to start off.

{
[
{
"Field1":"Value",
"Field2":"Value"
},
{
"Field1":"Value",
"Field2":"Value"
}
]
}
WilsonYu
Joined: Nov 6, 2013
Messages: 3950
Offline
How about verifying your string with this tool.

http://jsonlint.com/
MichaelDailous_deprecated
Joined: Nov 11, 2013
Messages: 171
Offline
Jsonlint shows results as "Valid JSON" (see attached JPG). As I said, my JSON string is formatted correctly, because my JSON array is an array of objects, not simple data types. Even if my JSON array were simple data types, the OD REST doesn't allow the MessageBody to contain *only* an array of items.

IMHO, it appears the OD REST code for the valid JSON messagebody text is only whitelisting the opening curly braces '{', and doesn't include the equally valid open bracket '['. I could be wrong, and I'm open to considering any other suggestions you have.

Michael
  • [Thumb - ValidJson.jpg]
[Disk] Download
MichaelDailous_deprecated
Joined: Nov 11, 2013
Messages: 171
Offline
I went ahead and entered the JSON string you suggested (starting and ending with curly braces), and jsonlint shows that as "Error". Please see the attached image. This further supports my theory.

Michael
  • [Thumb - JsonInvalid.jpg]
[Disk] Download
WilsonYu
Joined: Nov 6, 2013
Messages: 3950
Offline
Read my previous post carefully. That's not what I was suggesting. I suggested starting with a key when you enclose the whole thing with {}:

{
"key": [{
"field1": "value"
}, {
"field2": "value1"
}]
}
MichaelDailous_deprecated
Joined: Nov 11, 2013
Messages: 171
Offline
Adding a string element isn't a viable solution, as that requires the web service to be reworked, which will affect downstream applications. Not to mention, my JSON string is valid. It begins with an array indicator. Valid JSON strings can begin with any of the following:

  • Object - {

  • Array - [

  • String - "

  • Value - No wrapping - consisting of a number, true/false, or null


  • I ran some more tests on what is considered valid JSON in an OD REST client, and it appears the *only* JSON string OD considers *valid* is a JSON Object string. For any of the other elements, there is either

  • a StringIndexOutOfBoundsException (String and Value JSON strings from the list above, or an array of simple elements), or

  • if the array is an array of objects, the opening Array character is removed.


  • This renders the OD REST plugins only useful if the message body requires *only* an object string.

    The web service I'm trying to call from OD expects the message body to be a JSON array only, I can't change the web service due to the impact it will have.

    What other options do I have?
    Michael
    WilsonYu
    Joined: Nov 6, 2013
    Messages: 3950
    Offline
    I should've commented on your string which starts with "[" and ends with "]". A valid JSON object string always start with "{" and a key which identifies the root object. I think the reason you can validate your string with the online tool is that the tool takes it as a snippet.
    WilsonYu
    Joined: Nov 6, 2013
    Messages: 3950
    Offline
    If JSON does not work for you, you can use XML according to the code I am looking at.
    MichaelDailous_deprecated
    Joined: Nov 11, 2013
    Messages: 171
    Offline
    My string that starts with a '[' (a JSON array string) is valid according to JSON.org (http://json.org) and the JSON specification (https://tools.ietf.org/html/rfc7159#section-2).

    According to JSON.org:

    JSON is built on two structures:

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.

  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.


  • You may be correct in assuming that jslint.org wraps the entered JSON string into a json object, but that would make it's results untrustworthy. With this in mind, I tried out my JSON array string in a few other JSON validators:

  • https://jsonformatter.curiousconcept.com/ - Valid JSON (RFC 4627)

  • http://www.jsonschemavalidator.net/ - No errors found. JSON validates against the schema.

  • http://www.freeformatter.com/json-validator.html - The JSON input is valid according to RFC 24627 (JSON specification).


  • The results are copy/pasted from each validator. My JSON array string is valid.

    The bigger issue is that the OD REST client *only* accepts JSON objects, beginning with a curly brace. This is evident in the StringIndexOutOfBoundsException being thrown when a curly brace isn't present. The OD REST client needs to *also* accept valid JSON array strings that are not nested in objects (typically called a wrapper).

    Regarding using XML, how do I add the xml string to the messagebody? JSON requires the "JSON " indicator at the start, does the XML require an indicator as well?

    Thank you,
    Michael
    WilsonYu
    Joined: Nov 6, 2013
    Messages: 3950
    Offline
    I have yet to find one example on-line where people start the JSON string with "[". Also, I have not been able to find Java API and implementation that can parse the string into array of objects by simply providing the string without doing manual parsing. Our code just use the org.apach.axis2.json to deserialize the string into an object. So I am not so sure starting with "[" is a common practice.

    To use XML, you don't need to start with the "XML" notion.
    MichaelDailous_deprecated
    Joined: Nov 11, 2013
    Messages: 171
    Offline
    Here's an example on StackOverflow using the GSon library. Just because there aren't many examples doesn't mean array strings are not valid or they're not being used. I've personally used them in several projects that don't rely on OD.

    Out of curiously, why is the message body string being deserialized? The string is means for consumption on the server. The necessary classes for deserialization may not even be accessible to the OD client. I understand that's not a "typical" business case, either, but it's still a possibility. Just a thought, but since the message body string is meant to be consumed on the server, why not strip the "JSON" indicator, and just pass the body string as-is.

    Michael
    Go to:   
    Mobile view