From JSON website:
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.
Now I have a sample service that returns a boolean (this is in PHP, but it could be any server side language):
<?php
header('Content-Type: application/json');
echo 'true';
exit;
And when requesting this page with ajax (for example with jQuery):
$.ajax({
url: 'service.php',
dataType: 'json',
success: function (data) {
console.log(data);
console.log(typeof data);
}
});
The result would be:
-> true
-> boolean
My question is why it's allowed to return boolean as a JSON.
Doesn't it have conflict with JSON definition?
ALSO
Also I can return number or string in my service:
<?php
header('Content-Type: application/json');
echo '2013';
exit;
And the result is:
-> 2013
-> number
And for string:
<?php
header('Content-Type: application/json');
echo '"What is going on?"';
exit;
And the result is:
-> What is going on?
-> string
You are correct that a valid JSON text can only be an object or an array. I asked Douglas Crockford about this in 2009 and he confirmed it, saying "Strictly speaking, it is object|array, as in the RFC."
The JSON RFC specifies this in section 2:
A JSON text is a serialized object or array.
JSON-text = object / array
The original JSON syntax listed on json.org does not make this clear at all. It defines all of the JSON types, but it doesn't say anywhere which of these types may be used as a "JSON text" - a complete valid piece of JSON.
That's why I asked Doug about it and he referred me to the RFC. Unfortunately, he didn't follow up on my suggestion to update json.org to clarify this.
Probably because of this confusion, many JSON libraries will happily create and parse (invalid) JSON for a standalone string, number, boolean, etc. even though those aren't really valid JSON.
Some JSON parsers are more strict. For example, jsonlint.com rejects JSON texts such as 101, "abc", and true. It only accepts an object or array.
This distinction may not matter much if you're just generating JSON data for consumption in your own web app. After all, JSON.parse() is happy to parse it, and that probably holds true in all browsers.
But it is important if you ever generate JSON for other people to use. There you should follow the standard more strictly.
I would suggest following it even in your own app, partly because there's a practical benefit: By sending down an object instead of a bare string, you have a built-in place to add more information if you ever need to, in the form of additional properties in the object.
Along those lines, when I'm defining a JSON API, I never use an array at the topmost level. If what I have is an array of items of some sort, I still wrap it in an object:
{
"items": [
...
]
}
This is partly for the same reason: If I later want to add something else to the response, having the top level be an object makes that easy to do without disrupting any existing client code.
Perhaps more importantly, there's also a possible security risk with JSON arrays. (I think that risk only affects the use of eval() or the Function constructor to parse JSON, so you're safe with JSON.parse(), but I'm not 100% sure on this.)
Note, the answer from Michael Geary is outdated since rfc7158 in 2013 which does not limit JSON text to array or object anymore. The current RFC https://www.rfc-editor.org/rfc/rfc8259 says:
A JSON text is a serialized value. Note that certain previous
specifications of JSON constrained a JSON text to be an object or an
array. Implementations that generate only objects or arrays where a
JSON text is called for will be interoperable in the sense that all
implementations will accept these as conforming JSON texts.
Related
In netsuite i'm using the nlapiRequestURL to retrieve a JSON data from flexport, an overseas shipping company. I have have the data as a string(to my knowledge retrieving json data makes it a string) and want to turn it into an array of objects, but everything I have tried has resulted in various errors.
trying...
`var output = nlapiRequestURL(url,null,headers,"GET");
var split = JSON.parse(output.getBody());
response.write(split);`
gave me
{records=[Ljava.lang.Object;#7220fad}
and trying to show any element of split gave me undefined or that it cant read element from index.
I've ran the string through a JSON checker and it said it was a valid JSON file. I've done various variations of JSON.parse and looked tried Tostring. I've been working on this for a while and have no idea why I can't parse this information properly. Any help is appreciated.
You have parsed the result but then you are writing the parsed object which just gets you the object’s implementation dependent toString() output.
If you are just trying to echo the response re-stringify the parsed payload.
I have a Java JSON Object, its format is [{a=b}], I am trying to pass this object into javascript as a JSON object but its missing " on both the key and value as well as having "=" instead of ":"
Is there a simple way of converting this JAVA JSON object to be consumable by different services?
Parsing is proving to be very complicated as the actual JSON is nested and the lack of quotations and the lacking of indications for nestedness.
Sample of 'JSON' data:
[{wwnType=Virtual, serialNumberType=Virtual, connections=[], modified=2016-10-29T19:00:04.457Z, macType=Virtual, category=server-profile-templates, serverHardwareTypeUri=/rest/server-hardware-types/32006464-D3C6-4B4E-8328-47A193C6116C, bios={overriddenSettings=[], manageBios=false}, firmware={firmwareBaselineUri=null, manageFirmware=false, forceInstallFirmware=false, firmwareInstallType=null}, boot={manageBoot=true, order=[CD, Floppy, USB, HardDisk, PXE]}, hideUnusedFlexNics=true, bootMode=null, state=null, affinity=Bay, localStorage={controllers=[]}, type=ServerProfileTemplateV1, status=OK, description=, eTag=1477767604457/1, serverProfileDescription=test, name=test, created=2016-10-29T19:00:04.428Z, enclosureGroupUri=/rest/enclosure-groups/e989621b-930e-40e7-9db0-a6ddbf841709, uri=/rest/server-profile-templates/db1dbdcc-4237-4452-acc3-cf9dfdc75365, sanStorage={manageSanStorage=false, volumeAttachments=[]}}]
Thanks
It's not going to be simple. However, I think you can do this without writing a full-fledged parser, as long as you're willing to write a tokenizer, or lexical analyzer, to break your input string into tokens. The basic plan could be something like:
Convert your input into a list of tokens. I don't know what the format of your input is, so you'll need to do your own analysis. A token would be something like a single character [, ], {, }, comma, =; or an identifier (a or b in your example, but I don't know what the possible valid formats are); or, maybe, a string literal in quotes, or a numeric literal, depending on what your needs are.
Go through the string and replace the tokens you need to. Based on your example, I'd say that after a {: if the first token after that is an identifier, put it in quotes; if the second token after that is =, change it to :; if the third token after that is an identifier, put it in quotes. The same could be true after a comma, but you'll need to keep track of whether the comma is a separator for a list of key-value pairs in an object, or a list of values in an array. For that, you may need to keep a stack that you push whenever you see [ or {, and pop whenever you see } or ], so that you know whether you're inside an object or an array.
After you're done replacing everything, concatenate the tokens back together. The result should be a well-formed JSON object.
This is just a rough outline, since I really don't know all your requirements. You'll probably have to adapt this answer to meet your exact needs. But I hope this helps as a general idea of how you could approach the problem.
Sorry, I don't think there's a simpler answer, except that you might want to look into parser generators (see Yacc equivalent for Java). I haven't actually looked at any in Java, so I don't know how simple they are to use. Please don't try to solve the whole thing with regexes. (Regexes will be useful for breaking your string into tokens, but trying to do more than that with regexes is likely to produce nothing but migraine.)
I think isn't json object. json object should be like this.
Example:
JSONObject obj = new JSONObject();
obj.put("a", "b");
obj.put("name", "your name");
Output: {"a": "b", "name":"your name"}
Passing into javascript
var obj = '{"a": "b", "name":"your name"}',
var json = JSON.parse(obj);
I am just trying to parse a Json document with a field Date like this:
´ death':Date('2007-03-17T04:00:00Z') using
com.mongodb.util.JSON.parse(document)
There is an exception when the value Date is encountered. Any help?
The key here is whatever has exported the data has done it wrong. Possibly someone has run something from the MongoDB shell and redirecting console output to a file. That is basically "doing it wrong".
There is a concept called MongoDB Extended JSON and has in fact been picked up in a few other areas, notably the EJSON project.What this tries to do is make sure that any exported JSON maintains "type" information to the BSON type identifier ( or other Object Type, in the purpose of EJSON ) so that a similar "extended JSON" parser can "re-construct" the object to it's intended form.
For a "date" object, the intented JSON representation is this:
{ "death": { "$date": "2007-03-17T04:00:00Z" } }
Since com.mongodb.util.JSON.parse is enabled with knowledge of the Extended JSON spec, then any such JSON contruct will result in a correct date object being constructed from the parsed data.
So what you have right now is just a "string". In fact, if it is not "quoted" like this:
´ { "death" : "Date('2007-03-17T04:00:00Z')" }
Then it is not in fact even valid JSON and would even need to be manipulated to a correct form before even a basic JSON parser would not error. At any rate, the result is just a "string" still, so you would need to make a regex match for the numerical data, then pass that to a date object construct.
Clearly the "best" thing to do here is to fix the "export" source of the data so that it is doing this date parsing to JSON in the correct extended way. Then the parser you are using will do the right thing.
When I use ajax to post data from Javascript to PHP, the php $_POST variables are always strings. Is there any way to preserve the variable type when posting. EG when posting a boolean true I want a boolean true and not a string 'true'.
You can use JSON as format and the PHP json parser will do it for you.
You can find an example here:
http://php.net/manual/en/function.json-decode.php#90790
Not possible directly: values will always be initially read as strings on the PHP side.
If you need to coerce the values into other types and cannot hardcode these types in your code you will need to arrange for "type information" to be passed to PHP (also as a string). That's how protocols that inherently provide data type support, such as SOAP, work.
As said above, you can let the JSON parser be do it for you.
You can also try it by yourself by checking the values.
Like boolean: is_bool
http://php.net/manual/en/function.is-bool.php
Like int: is_int
http://php.net/manual/en/function.is-int.php
etc.
This can be done when you have the POST values, and check for example the number field if it is a int:
<?php
$numberIsInt = is_int($_POST["number"]);
if($numberIsInt) {
//Do something
} else {
//Return error or do something else
}
?>
I've seen so many complicated questions in SO whether or not some complicated structure is considered to be valid JSON.
But what about something on the other end of the spectrum?
"12345"
Is the above valid JSON?
Yes, in most contexts. It is valid JSON syntax representing a JSON value.
The confusion around this comes from Douglas Crockford's RFC 4627, which originally defined the application/json internet media type in 2006. It said that:
A JSON text is a serialized object or array.
However, as Crockford explained in a post in 2013 (unfortunately deleted with rest of Google+, but archived here):
JSON is just a grammar, and the grammar includes numbers and strings. Uses of JSON must necessarily be more restrictive. RFC-4627 is one possible use, and was never intended to be the standard for JSON itself.
The example string is a valid JSON value, but it would have been incorrect to use it as the full "JSON text" body of an application/json HTTP response. However, that's no longer true: RFC-4627 was obsoleted in 2014 with the publication of RFC 7159, which lets you use any JSON value:
A JSON text is a serialized value. Note that certain previous specifications of JSON constrained a JSON text to be an object or an array.
A "standard for JSON itself" was also published in 2013, as ECMA-404, and JSON was also defined in edition 5.1 of the ECMAScript (JavaScript) specification ECMA-262. These specifications and most parsers allow any JSON value as a complete JSON text, even if it's just a simple string.
As of 2014, RFC 7159 obsoletes the older JSON RFCs, and declares that any JSON value is valid JSON text and valid application/json content - including strings. However, it also points out the incompatibility issue with older JSON implementations:
Note that certain previous specifications of JSON constrained a
JSON text to be an object or an array. Implementations that
generate only objects or arrays where a JSON text is called for
will be interoperable in the sense that all implementations will
accept these as conforming JSON texts.
Its a valid JSON string, but its not a JSON object.
See http://www.json.org/
At the time this question was written, this would not have been a valid JSON text. It would have been a valid string that could appear as part of a JSON text.
The original specification said:
A JSON text is a serialized object or array.
… meaning that the top level had to be {} or []. You couldn't dive straight in with a string.
The latest specification says:
A JSON text is a serialized value. Note that certain previous specifications of JSON constrained a JSON text to be an object or an array.
So now any value, including a string, can be a complete JSON text and "12345" is now valid.
You can simply check what JSON.parse can handle:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#examples
This is all valid JSON:
JSON.parse('{}'); // {}
JSON.parse('true'); // true
JSON.parse('"foo"'); // "foo"
JSON.parse('[1, 5, "false"]'); // [1, 5, "false"]
JSON.parse('null'); // null