Why does WebView.evaluateJavascript() remove escape characters? - android

I have a stringified JSON object that I want to pass into my WebView as a string. If my JSON string is a simple one-level JSON like this:
JSONObject object = new JSONObject;
object.put("key1", "val1");
object.put("key2", "val2");
String myValue = object.toString();
And I run evaluateJavascript like this:
webView.evaluateJavascript("console.log('" + myValue + "')", null)
Then the console log I get is this:
{"key1": "val1", "key2", "val2"}
Which is correct.
But if my JSON has a sub JSON inside it, then the stringified version of that JSON should have escaped quotes in it for that inner JSON. So if I did this:
JSONObject object = new JSONObject();
object.put("key1", "val1");
JSONObject innerObject = new JSONObject();
innerObject.put("key3","val3");
object.put("key2", innerObject);
String myValue = object.toString();
And run the same evaluateJavascript statement above, I get the following console log
{"key1":"val1", "key2": "{"key3": "val3"}"}
Which is not what I am expecting! I'm expecting an output like this:
{"key1":"val1", "key2": "{\"key3\": \"val3\"}"}
The quotes of the inner JSON are supposed to be escaped. If they are not escaped, then trying to run a JSON.parse on it will result in a parse error.
I even used a debugger to inspect the run time value of myValue just before it is passed into evaluateJavascript and it looks the way it's supposed to:
"{"key1":"val1", "key2": "{\"key3\": \"val3\"}"}"
So why does running evaluateJavascript mysteriously strip away those explicit escape symbols?
NOTE:
The only way I could solve this was to run the following statement just before evaluateJavascript
myValue.replace("\\", "\\\\")
That is, replacing any escape characters (\) with 2 escape characters (\\). That way, the mysterious stripping will remove one escape character but leave the other one there which allows me to successfully JSON.parse it.

You can use URLEncode to encode the contents while using javascript interface.
URLEncoder.encode(contents, "UTF-8");
And then for getting back the actual contents in js you can use
decodeURIComponent(contents.replace(/\+/g, '%20'));

Related

Escape / encode double quotes in string before sending via post request

I'm sending string below from Android to web service using volley request
params.put("data", objData.toString());
objData.toString() -->
{"report_time":1413876429,"device_id":"13d404d1b3a38ffc","ads_info":"[{\"play_count\":\"26\",\"ad_id\":\"21\"},{\"play_count\":\"58\",\"ad_id\":\"37\"},{\"play_count\":\"14\",\"ad_id\":\"40\"}]"}
Server not accepting it due the \"
How to remove \ keeping the json correct ""
You are not using the web service correctly.
Possibly the service expects to see a JSON array instead of a string containing JSON. Assuming params is a JSONObject and objData is a JSONArray, use params.put("data", objData) instead of the toString() version you have now.
Escaping the double quotes with backslashes is the only way to do this in java.
One other option would be to put the String into some kind of text file that you would then read at runtime.

Iterating through JsonObject in Java/Android. NOT JsonArray

Here's my JSON data sample:
{
"node_1.1":{
"someCrap":{
"someCrap":"SomeValue"
}
},
"node_1.2":{
"Node_1.2.1":{
"Node_1.2.1.1":{
"param1":value,
"param2":value,
"param3":"value",
"paramThatIneed":{
"ThisIsWhatIActuallyNeed":"url",
"width":96,
"height":72
}
},
"Node_1.2.1.2":{
Same as above, just that paramThatINeed might be missing, gotta place imagePlaceHolder Here
},
//and so on... there are a total of 50 of these..
}
}
}
Now I could get the node_1.1 and Node 1.2 and the sub-node of it node_1.2.1
However, there are 50 sub-nodes inside of node_1.2.1, and they will have random names returned from the server. Its in string format but they're actually ints. Its a page ID.
Now I wanna iterate through the node_1.2.1 and get those sub-nodes and access their sub-nodes and take in the URL of the paramThatINeed. If the paramThatINeed is not present, I need to put some null/dummy value.
This is the code that I tried to work it as far as I've reached:
JSONObject jsonObj = new JSONObject(jsonStr); //jsonStr is the entire JSON string
JsonObject node_1.2= jsonObj.getJsonObject("node_1.1");
JsonObject node_1.2.1 = node_1.2.getJsonObject("node_1.2.1");
What do I do after this? Because I can only getJsonObject by passing a string param to it, I tried using the for loop but it doesn't take any int param.
Also, as I said before, the nodes after that have random names and not fixed. So I'm totally confused.
Please help me out if you know how to solve this problem. Please remember there's no JsonArray in this. I'm probably thinking of editing the JSON string itself and replacing some parts of the '{' with '[' and converting it to an array :( ... I think that's a sad approach.
Use this to iterate over an object.
Android (JSONObject) How can I loop through a flat JSON object to get each key and each value
but be careful, from json object you won't get the result in original order, like in json array. The result will be in alphabetical order (I hope I was clear). And you can use optJsonobject(), instead of getJsonObject(). It will returns null, instead of throw exception. You can use opt every where instead of get.

How to put a string variable in JSONObject

I have a JSONObject:
JSONObject data = new JSONObject("{\"alert\": \"The Mets scored!\", \"action\": \"com.vipulk.acuv.UPDATE_STATUS\",\"ph\": ph }");
I have a string defined as:
String ph="this is String";
Now when i receive this JSONObject on receiver side I have the value of "ph" as "ph". I want the value of original String ph. How to do it. Can JSONObject send extra strings with another method.
Pardon my limited knowledge about JSON, as I am using it just once so I am avoiding going deep. I have everything done except putting this string variable in JSONObject.
NOTE: I am working with PARSE push notifications and I've to send this object in a push notification (that i am able to do).
If you want to modify your JSONObject, you can use .put method (http://json.org/javadoc/org/json/JSONObject.html#put%28java.lang.String,%20java.lang.Object%29):
data.put("ph", ph);

Adding link to json object in android

JSONArray albumarray=new JSONArray();
JSONObject imgobj=new JSONObject();
imgobj.put("thumb", filepath.get(i));
imgobj.put("main", filepath.get(i));
albumarray.put(imgobj);
JSONObject albumjson=new JSONObject();
albumjson.put(albumname,albumarray);
When I convert albumjson to string using
albumjson.toString()
I am getting output as below.
{\"test2\":\"[{\\\"thumb\\\":\\\"http:\\\\\\/\\\\\\/dev.mysite.in\\\\\\/mysite\\\\\\/sites\\\\\\/default\\\\\\/files\\\\\\/512da541b31fe.jpg\\\",\\\"main\\\":\\\"http:\\\\\\/\\\\\\/dev.mysite.in\\\\\\/mysite\\\\\\/sites\\\\\\/default\\\\\\/files\\\\\\/512da541b31fe.jpg\\\"}]\"}
the correct format i need is
{"test2":[{"thumb":"http://dev.mysite.in/mysite/sites/default/files/512d9bdced1f2.jpg","main":"http://dev.mysite.in/mysite/sites/default/files/512d9bdced1f2.jpg"},{"thumb":"http://dev.mysite.in/mysite/sites/default/files/512d9be134cb8.jpg","main":"http://dev.mysite.in/mysite/sites/default/files/512d9be134cb8.jpg"}]}
How to replace additional slashes.
PLease use JSONObject.getString('keyName') method instead of toString()
EDIT:
You should first understand why those extra \\ are showing up.It is an escape character for ".Hence,it is very much required there and is a part of JSON encoding .Hence,one should always use the above method to get values of keys whenever needed.
apart from that you can try :
JSONObject.toString(4) where 4 is actually indent spaces and see whether it helps.Otherwise there's simply no other option than to replace those extra \\ like
myJsonString.replaceAll("\\","");
or
myJsonString=myJsonString.replaceAll("\\\\","");
SECOND EDIT:
The string you are sending is perfect to send to any server.You need to decode that string at the server end to JSON and then utilise it.
If you are using .NET you can see this. Or if you are on some other platform you need to find out how to decode to JSON on that platform.
There are two things going on here:
Your tools are confusing you. When it shows the output:
"{\"test2\":\"[{\\\"thumb\\\":\\\"http:\\\\\\/\\\\\\/dev.lrcdn.in\\\\\\/shiaspark\\\\\\/sites\\\\\\/default\\\\\\/files\\\\\\/512da541b31fe.jpg\\\",\\\"main\\\":\\\"http:\\\\\\/\\\\\\/dev.lrcdn.in\\\\\\/shiaspark\\\\\\/sites\\\\\\/default\\\\\\/files\\\\\\/512da541b31fe.jpg\\\"}]\"}"
It is telling you that the result is a string containing:
{"test2":"[{\"thumb\":\"http:\\\/\\\/dev.lrcdn.in\\\/shiaspark\\\/sites\\\/default\\\/files\\\/512da541b31fe.jpg\",\"main\":\"http:\\\/\\\/dev.lrcdn.in\\\/shiaspark\\\/sites\\\/default\\\/files\\\/512da541b31fe.jpg\"}]"}
Taking that string and formatting it:
{"test2":
"[{\"thumb\":\"http:\\\/\\\/dev.lrcdn.in\\\/shiaspark\\\/sites\\\/default\\\/files\\\/512da541b31fe.jpg\",\"main\":\"http:\\\/\\\/dev.lrcdn.in\\\/shiaspark\\\/sites\\\/default\\\/files\\\/512da541b31fe.jpg\"}]"
}
We can see that you've constructed a json object containing a json-encoded string, rather than a nested jsonobject. For whatever reason, your code is having the effect of:
JSONArray albumarray=new JSONArray();
JSONObject imgobj=new JSONObject();
imgobj.put("thumb", filepath.get(i));
imgobj.put("main", filepath.get(i));
albumarray.put(imgobj);
JSONObject albumjson = new JSONObject();
albumjson.put(albumname, albumarray.toString());
That sounds like a bug in your json library

Json string mutating

I have a .Net WCF Rest service returning Json to be consumed by an Android app.
In debug, the WCF service correctly has the return value (Json) as:
{"BaseLoyaltyPoints":1480,"BonusLoyaltyPoints":0,"BrandId":1414, [etc...] }
Also in debug, when it returns to Notepad, the return value has changed to:
{\"BaseLoyaltyPoints\":1480,\"BonusLoyaltyPoints\":0,\"BrandId\":1414, [etc...] }
And when it gets to my Android app, it has become:
{\\"BaseLoyaltyPoints\\":1480,\\"BonusLoyaltyPoints\\":0,\\"BrandId\\":1414, [etc...] }
This is the boilerplate code I am using to serialize the Json:
Dim stream1 As MemoryStream = New MemoryStream
Dim ser As DataContractJsonSerializer = New DataContractJsonSerializer(GetType(FullProduct))
ser.WriteObject(stream1, Me)
Dim _json As String = Encoding.UTF8.GetString(stream1.ToArray())
stream1.Close()
The Android code to get the Json is:
HttpClient httpclient = new DefaultHttpClient();
HttpGet request = new HttpGet(getString(R.string.CONST_RestService) + "/json/Product/" + productID);
ResponseHandler<String> handler = new BasicResponseHandler();
result = httpclient.execute(request, handler);
jObject = new JSONObject(result);
What's going on?
Thanks
Dave
The JSON Data needs to be an evaluable JavaScript String - the " character needs to be escaped to \" (the character " as opposed to the String limitor "), and the \ in that expression needs to be escaped as well (because \ also is a special character). So it has been that string all along, it was just printed differently everytime.
Take this JavaScript for an example:
object = JSON.parse("{\"hello\":\"World\"}");
alert(object.hello);
The following is more of a guess than actual knowledge, because I do not know how exactly the classes you used behave, but I think that it's about right.
As you can see, the " characters need to be escaped to \", so your .NET JSON serializer does just that. Everything is fine, interpreting this as JS would work as expected.
Now what is probably going on is that your JSONObject constructor does not expect Strings to be already properly escaped, so it does that itself. To clarify: When you say "with one escape character", you probably mean something like this:
String workingJSONString = "{\"Hello\":\"World\"}"
right? The problem here is that Java has the same escaping rules as JavaScript - this is not what you get from your HTTPRequest, what you get is
String youGotThis = "{\\\"Hello\\\":\\\"World\\\"}"
Because there are literal backslashes in your String, and those need to be escaped as well. I am pretty certain that that is what is going on, and you'd probably either have to tell your .NET JSON serializer not to apply escape rules or find something that constructs a JSONObject from a properly escaped JSON string - or remove the unnecessary escapes yourself.
I hope this helped - but again, I am not fully certain so you should just check out if it actually behaves as I said.

Categories

Resources