Why json is parsed diffrently on diffrent application environments? - javascript

I have json object in java, which I return to browser using obj.toString(). response.setContentType("application/json") is setting return type to json.
example:
obj = {
name: "pp",
age: 24
}
Application on tomcat: response received is
obj = {
name: "pp",
age: 24
}
but Application on glassfish: response received is
obj = {
name: "pp",
age: "24"
}
Notice that age is treated as string which is causing lot of problem.
Above is just an dummy json, I am having huge json with lot of key's and values and most of the values are Integer or floats. So How Can i get json in which data type of values are preserved.

In application as it is very old appication initialy we used xml response. While upgrading the sytem we went for json response. To reduce code change, we just converted the xml to json using function in json.jar.
JSONObject xmlJSONObj = XML.toJSONObject(returnStrXML);
Problem was here while converting xml to json. In my environment i had diffrent jar which smartly converted xml in json perserving its data types. While the json.jar converts all the values to string by default. Changing the jar solved the problem.

Related

How is JSON related to serialization?

What is serialization?
Serialization is the process of converting the object into stream of bytes to send it over a network or store it in a file in such a way that the object can be reconstructed again.
What is JSON?
JSON is the data interchange format, having a fixed structure. When de-serialized it return the Javascript object.
I did some Googling but can't find the how they are related? They are often mentioned together. I need to know what is going on under the hood when we say that we need to serialize the data in JSON.
JSON is basically structured text.
One example would be a client-server architecture, such as web browser - server communication is. The data from the server can be serialized from native format to JSON (text) and transferred through the network (stream of bytes) to the client (web browser). When the data gets to the client (web browser), it is deserialized to a Javascript object and handled (maybe something is displayed to the user or the UI manipulated - non-essential).
A Java example
Let's say we've a simple class in our server application, which is written in Java:
class Person {
String name;
int age;
}
and we've an instance of this class:
Person person = new Person();
person.name = "John";
person.age = 32;
We've chosen to use JSON as the data format in server-to-client communications. Converting our instance of a person to JSON looks like this:
String json = "{\"person\": {\"name\": \"John\", \"age\": 32} }";
Now we just write this String to HTTP response, from where the client reads it - to a string. The string is then deserialized to a Javascript object. Deserialization could look like this (more about JSON.parse at MDN / JSON.parse):
/* We get responseText by AJAX and it looks exactly the same that we sent from our web
server - IT IS TEXT, the variable 'json' contents in our Java application. */
var responseText = "..."
var data = JSON.parse( responseText ); // JSON.parse is supported by modern browsers
Data looks something like this if written directly as a Javascript object:
data = {
person: {
name: john,
age: 32
}
};
So, we started in the server side from a Java-object. We serialized the Java-object to a JSON-string and sent it through the network to the client. The client deserialized the JSON-string to a Javascript-object (which can be properly dealt with in language-specific way).
JSON is a format that allows you to represent your objects as a string / text, which can then be stored, sent etc.
Another example would be XML, which is also often used for serialization.
Example:
Object
var Person = new Object();
Person.FirstName = "Foo";
Person.LastName = "Foo";
Person.Age = 24;
JSON example serialization
{
Person:
{
FirstName: "Foo",
LastName: "Bar",
Age: 42
}
}
XML example serialization
<Person>
<FirstName>Foo</FirstName>
<LastName>Bar</LastName>
<Age>42</Age>
</Person>
Since you asked "what is going on under the hood": Simply explained, the serialization algorithm would iterate all properties of the object and store their names and values in a string of the requested format (JSON, XML, ...)
JSON represent collections of key/value pairs. JSON Parsers (like JSON.parse, json_decode) will map this representation to an appropriate data structure that reflects these collections. JSON Serializers (like JSON.stringify, json_encode) do the inverse, they take a data structure and map it to JSON.
For example in PHP:
$obj['a'] = 'b'; //Associative Array
$obj['c'] = 'd';
Its JSON representation would be:
'{
"a" : "b",
"c" : "d"
}'
Keys and values of the respective data structure (in this case an associative array).
In Javascript:
var obj = {
a : 'b',
c : 'd'
}
This is a Javascript object, when serialized it maps to the same JSON:
'{
"a" : "b",
"c" : "d"
}'
JSON describes a precise string format, which is why I've marked my JSON in between ' '. A string representation of your data structures can be very useful for many things, like sending them as a message.

Converting JavaScript JSON data to Python JSON

I have JavaScript JSON data:
var data = '{a: 10, b: 20}'
I want to convert it to Python JSON. How can I do?
My situation:
I have script that read text from a website. website has data in javascript variables like I show in example. I extracted variable part '{a: 10, b: 20}'. But for the python, it is still string format. I need to convert that data into Python JSON so I can do further work.
How can I convert JavaScript JSON to Python JSON?
Python JSON is a bit of a misnomer as JSON (as in JavaScript Object Notation) is a subset of JavaScript and simply describes a JavaScript object. It is an exchange format that does not depend on the language you are using it with.
You can use the json module to parse JSON in Python, and return an equivalent Python object.
it need regex replace before can convert it json
import re
import json
data = '''{a: 10, b: true, c :"string", "d" : jsVariable, e:'single'}'''
# replace single with double quote
data = data.replace("'", '"')
# wrap key with double quotes
data = re.sub(r"(\w+)\s?:", r'"\1":', data)
# wrap value with double quotes
# but not for interger or boolean
data = re.sub(r":\s?(?!(\d+|true|false))(\w+)", r':"\2"', data)
data = json.loads(data)
print(data['a']) # 10
print(json.dumps(data, indent=2)) # formatted json string
Apparently some libraries like RSON can help you.
According to that answer
var data = '{a: 10, b: 20}' is not a valid JSON. It is valid JavaScript
If you were to do
var data = JSON.stringify({ a: 10, b: 20 });
you would find it actually becomes
var data = '{ "a": 10, "b": 20 }'
The extra " around the a and b variables being the part that makes this valid JSON. The confusion comes from the fact that JavaScript is more forgiving than JSON.
Don't feel bad. You will not be the only one who will fall into this trap.

What String format is acceptable to append to this JSON output?

I have an existing "blackbox" web service. I need to append a session ID to the end of that output so that Javascript and similar clients can resume the stateful session.
Given the output below, what is the correct syntax to append or prepend an arbitrary GUID, so that it can be properly deserialized as valid JSON?
Note This data below is perfect. If I can somehow add a "removable" bit of information, using JSON.NET the string GUID, that would be ideal.
Output from REST call
"{\"sa\":[\"BHDQ9TLPeaeVuSSgXv9bsOIVFUWbOpivMKhGki7YPLzIXEyHuxRAZhDgts2sEcBQpLBuKJZCtcmSlzWZ9iK0AAA=\",\"BAhyo7T0Wq1WBLXnyN4vo1L94rWLhCCv4DqROi+p9XHO6UeS0Gw6xh1JAKOtXBU2fA432LkNqng8cUt1eAX0bqs=\",\"BGFmyTreWY5pICAcf3itoqbfhs5brOmIDLNF3V7p7slPYdCSVhwWUT5mHD6Lb5kNi\/Qy9tracNUtVgvo3f51FrI=\",\"BMV7RIwoz+LdFgD2fq7UZ7E88KFq\/03381NDYFIKYgUKxEzuXoj6hZfSB0slX5fdaL44Lf6i\/UjDzPQt2XUG8NE=\",\"BL8BnU5WvFn7vIlKi14dWsqykNf1\/nmE55YXFGwLx9Qu3VvDblULt\/U8CXPI1vD8+wMXCRnkunXqxlsFqgghf8w=\"],\"sb\":[\"BInTtgTAn\/zkmrkporhV5DvPZRq5YWm8e\/m02oq55UfY3RxIhOplJgwLjgKMHKYDthYEBcqNNNuVbbWnbtKVAqA=\",\"BJbh5y95wHGjmAPDFNqgewnBxtqVke0sloDD2S3IdrWZ95JfP77rtXZ4lTG8g9PuTLJbl4exZUnM16260WxJ9wU=\",\"BKevE9i2J8CicXHX3elCoQPEpTOmJyGOlBskIbFMFGQFhJ5TD7N1221rhhH9HY6DsfRojmefozsQYzo7Pokp+Hg=\",\"BJbVTRyh8WwCxfR7jRXnran4td7k5+vEfM+HWxeAibneSjdMRQ1Fg6QxKLu+Zu1aPdXqD8M29kABOTAiYopVuQE=\",\"BFv3alDqjo7ckdB2vuxJ15Gur1xsgATjLe9drt\/XU9AkbN+AELCv+mF1Xy8+83L2A1p8aGxF4b7dsrMed27u1j4=\"],\"sz\":\"BF1IiqMz0KmT4gZN6euJquWFt2UmVjyOEdaX0jH8uQMAPG8DBoyneT2PJ9NQTE2xBOP9TtAb1d2O+iCojFqzkvI=\"}"
The output above comes from Chrome. I'm not sure if Chrome adds additional quotes, etc but when I debug System.String on the server, I see the same thing being sent to the WCF service.
The end-usage for this will be a Chrome and Firefox plug in
Well if I am correctly understanding:
You get JSON from a blackbox service. It contains some properties and values. You want to add a new property with some GUID and send it to browser.
If this is correct, try following:
var json=<WHAT YOU GET FROM SERVICE>;
var converter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, converter);
obj.sid="this is the new session id"; //ADD NEW PROPERTY
var j=JsonConvert.SerializeObject(obj); //GET BACK JSON STRING WITH NEW PROPERTY
Of if you just want to add session id on client side (inside your plugin) the utilize JSON2 javascript library and use following code (as also suggested by Josh in comments):
var o = JSON.parse(<REST OUTPUT>);
o.sid = <YOUR SESSION ID>;
To convert back to JSON string.
var jsn = JSON.stringify(o);
There is no way to modify that particular response without breaking existing clients. If you can break existing clients, or if you are working with clients that you control, you could wrap the object in another object, setting two keys: GUID and data. For example:
var json = JsonConvert.SerializeObject(new {
data = foo,
GUID = bar,
});
Where bar is the GUID that you want to use, and foo is one of two things:
The JSON string from the response. This will result in the final object looking like so:
{
data: "{\"sa\":[\"BHDQ9TLPeaeVuSSgXv9bsOIVFUWbOpivMKhGki7YPLzIXEyHuxRAZhDgts2sEcBQpLBuKJZCtcmSlzWZ9iK0AAA=\",\"BAhyo7T0Wq1WBLXnyN4vo1L94rWLhCCv4DqROi+p9XHO6UeS0Gw6xh1JAKOtXBU2fA432LkNqng8cUt1eAX0bqs=\",\"BGFmyTreWY5pICAcf3itoqbfhs5brOmIDLNF3V7p7slPYdCSVhwWUT5mHD6Lb5kNi\/Qy9tracNUtVgvo3f51FrI=\",\"BMV7RIwoz+LdFgD2fq7UZ7E88KFq\/03381NDYFIKYgUKxEzuXoj6hZfSB0slX5fdaL44Lf6i\/UjDzPQt2XUG8NE=\",\"BL8BnU5WvFn7vIlKi14dWsqykNf1\/nmE55YXFGwLx9Qu3VvDblULt\/U8CXPI1vD8+wMXCRnkunXqxlsFqgghf8w=\"],\"sb\":[\"BInTtgTAn\/zkmrkporhV5DvPZRq5YWm8e\/m02oq55UfY3RxIhOplJgwLjgKMHKYDthYEBcqNNNuVbbWnbtKVAqA=\",\"BJbh5y95wHGjmAPDFNqgewnBxtqVke0sloDD2S3IdrWZ95JfP77rtXZ4lTG8g9PuTLJbl4exZUnM16260WxJ9wU=\",\"BKevE9i2J8CicXHX3elCoQPEpTOmJyGOlBskIbFMFGQFhJ5TD7N1221rhhH9HY6DsfRojmefozsQYzo7Pokp+Hg=\",\"BJbVTRyh8WwCxfR7jRXnran4td7k5+vEfM+HWxeAibneSjdMRQ1Fg6QxKLu+Zu1aPdXqD8M29kABOTAiYopVuQE=\",\"BFv3alDqjo7ckdB2vuxJ15Gur1xsgATjLe9drt\/XU9AkbN+AELCv+mF1Xy8+83L2A1p8aGxF4b7dsrMed27u1j4=\"],\"sz\":\"BF1IiqMz0KmT4gZN6euJquWFt2UmVjyOEdaX0jH8uQMAPG8DBoyneT2PJ9NQTE2xBOP9TtAb1d2O+iCojFqzkvI=\"}",
guid: "00000000-0000-0000-0000-000000000000"
}
And you would get at the data through two calls to JSON.parse (or the equivalent).
The deserialized object from the JSON response. This will result in the final object looking like so (most data removed for brevity sake):
{
data: {
sa: [],
sb: [],
sz: ""
},
guid: "00000000-0000-0000-0000-000000000000"
}
And you would access data through response.data.
Why any modification can break existing clients
Where the current response is an object, there are only a few ways to modify it:
Injecting a key into the object. This assumes that no client uses Object.keys() or in any way iterates the key set (e.g. for (k in obj)). While this may be true, this is an assumption.
Adding another object to the end: }, {. Doing so would require that the response be transformed into an array:
[{}, {}]
This would break any client that is assumes the response is an object.
Wrapping the current response in a surrounding object (as proposed above). This as well breaks any clients that assumes a certain structure for the response.
{data:{}, guid: ""}

JSON.parse parsing JSON with nested objects

I'm attempting to parse a JSON string with nested objects received in the response of a post request. After running JSON.parse(responseText), the result is in the following format:
[{
"atco":"43000156407",
"location":{
"longitude":"-1.7876500000000000",
"latitude":"52.4147200000000000","
timestamp":"2013-03-19 11:30:00"
},
"name":"Solihull Station Interchange",
"road":"STATION APPROACH",
"direction":"NA",
"locality":"Solihull",
"town":"Solihull"}, ...
I thought I would then be able pull values out using the following as an example, but all I get is undefined.
var atco = json[0].atco;
I've also tried json[0][0] but that returns an individual character from the JSON ([) . Does this indicate the JSON hasn't parsed correctly, or is this expected behaviour and I'm just referencing incorrectly?
This means that your JSON is being double encoded. Make sure you only encode it once on the server.
As proof, after you've parsed it, parse it again.
var parsed = JSON.parse(resposneText);
var parsed2 = JSON.parse(parsed);
alert(parsed2.atco);
Either that, or you're parsing it but then trying to select the data from the original string. This would obviously not work.

How to send js array via ajax?

I can only send string or numeric values,how to send an array?
You'll probably get a slew of answers all saying "JSON".
Here are some case specific examples. 'data' holds what you send.
var numArray = [17, 42, 23];
data = '[' + numArray + ']';
var strArray = ['foo', 'bar', 'baz'];
data = '["' + numArray.join('", "') + '"]';
For the general case, use a function that recursively encodes objects to JSON. If you really want me to, I'll post an example implementation, but it's a fun project so you might want to give it a try. If you're using a Javascript library, it might have a JSON encoder of it's own (such as jQuery's serializeArray).
There's are no built-in JSON serializers in javascript so you will need to use a library. A good one is json2.js.
Here's a sample:
// suppose you have an array of some objects:
var array = [{ prop1: 'value1', prop2: 10 }, { prop1: 'value2', prop2: 20 }];
// convert it to json string:
var jsonString = JSON.stringify(array);
// TODO: send the jsonString variable as a parameter in an ajax request
// On the server side you will need a JSON deserializer
// to convert values back to an array of objects
I can only send string or numeric values
Actually you can only send strings. When you include a number it is just turned into a string; it's up to the server-side script to parse that back into a number if it wants to.
how to send an array?
The native HTML-forms way of sending multiple values is using multiple inputs. You can reproduce this by including the same named parameter multiple times. To send [1,2,3]:
http://www.example.com/ajax.script?a=1&a=2&a=3
The same multiple-parameter-instance query string can be sent in an AJAX post request.
If you are using a higher-level framework to create the form-encoded string, it depends on the framework how it accepts multiple parameter instances. For example with jQuery you can post an object like {a: [1,2,3]}.
The other way is to forget the standard HTML form encoding and just pass all your values in whatever special encoding you like that allows you to retain datatypes and structure. Usually this would be JavaScript value literals (JSON):
http://www.example.com/ajax.script?a=%5B1%2C2%2C3%D
(that is, [1,2,3], URL-encoded.) You then need a JSON parser on the server to recreate native array values there.
You can actually send Arrays in a much cleaner way instead of trying to encoding JSON.
For example, this works
$.post("yourapp.php", { 'data[]': ["iphone", "galaxy"] });
See http://api.jquery.com/jQuery.post/ for more.

Categories