I'm trying to pass json data from javascript to java, like below. The idea is to pass the data to the java code as a javascript object (and not a a string which I know can be done ). I've tried the code below without success - idea was to use NativeJson.stringify to convert from a javascript object to a Java string, however this results in an Undefined instance instead of the expected string. Any idea on this could be achieved much appreciated.
in javascript file "test.js"
parser.fct ( {"abc":123,"def":456} )
in java
//1.binds javascript calls to Java
...
ScriptEngine engine = new ScriptEngine...
Bindings bindings = engine.createBindings();
bindings.put("parser", new Parser());
engine.eval("test.js");
//2. in Parser class
public void fct(Object obj){
Context ctx = Context.enter();
ScriptableObject scope = ctx.initStandardObjects();
Object json = NativeJSON.stringify(ctx, scope, obj, null,null);
//json returned is of type Undefined
}
Could not find a way to use NativeJSON.stringify(). I ended up building the json string "by hand", i.e Iterating on the property ids of the native javascript object and adding these properties to a java Map.
The Map is then transformed into a json object using new JSONObject(map);
link to source code
https://gist.github.com/eleco/c2bc77dca9ecc844a924
Related
I have to send a serialized object from java to javascript with jxbrowser and I do this like this
String json = objectMapper.writeValueAsString(value);
JSValue window = browser.executeJavaScriptAndReturnValue("window");
window.asObject().setProperty(requestName, json);
As far as I know it will set a object in global window as requestName? It is true?
And in another way how I can read this object from java site. This code is ok?
JSValue window = browser.executeJavaScriptAndReturnValue("window."+requestName);
T t = objectMapper.readValue(window.toString(), clazz))
Thanks in advance
Hi there are two aspects here.
Javascript execution context
JSValue that can be a plain value or a JavaScript object.
Once you invoke executeJavaScriptAndReturnValue your execution context is complete. And you can evaluate the returned object. This returned object can be a Java script object with functions in which case you can access it.
Lets say that your JavaScriptObject has a method helloWorld which accepts string.
JSValue document = browser.executeJavaScriptAndReturnValue("myJavascriptObject");
JSValue write = document.asObject().getProperty("helloWorldMethod");
write.asFunction().invoke(document.asObject(), "To Me");
This way we have passed the "To Me" string to the helloWorldMethod.
You can also set properties on the Object and invoke later another method. If this method uses this property, than within the next execution it will be taken into account:
JSValue document = browser.executeJavaScriptAndReturnValue("myJavascriptObject");
JSValue write = document.asObject().getProperty("helloWorldMethod");
document.asObject().setProperty("shouldISayGoodByeInstead",true)
write.asFunction().invoke(document.asObject(), "To Me");
The property shouldISayGoodByeInstead will be evaluated as part of the second execution which happens when helloWorldMethod is invoked, not during the first execution of executeJavaScriptAndReturnValue.
If I understand you correctly, you want to set a JavaScript object through JSON. This can be achieved via the JSONString. You can check the example here: https://jxbrowser.support.teamdev.com/support/solutions/articles/9000013064-working-with-json
After that, you want to get the JSON object. For this case, there is a method
JSObject.toJSONString()
So if we change your sample in the following way, it should work as expected:
String json = objectMapper.writeValueAsString(value);
JSValue window = browser.executeJavaScriptAndReturnValue("window");
window.asObject().setProperty(requestName, new JSONString(json));
JSValue window = browser.executeJavaScriptAndReturnValue("window."+requestName);
T t = objectMapper.readValue(window.asObject().toJSONString(), clazz))
I'm trying to update data in Elastic Search in my Java program with TranportClient class. I know I can UPDATE in this way :
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
.field("source.ivarId", source.ivarId)
.field("source.channel", source.channel)
.field("source.bacId", source.bacId).endObject();
UpdateResponse response = client.prepareUpdate(_index, _type, _id).setDoc(builder.string()).get();
while source is my user-defined class which contains 3 fields : ivarId, channel and bacId.
But I want to know is there any method that could do the same thing, but using another more efficient and easier way, so that I don't need to assign each field inside a class? For example, can I do like this?
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
.field("source", source).endObject();
UpdateResponse response = client.prepareUpdate(_index, _type, _id).setDoc(builder.string()).get();
I tried the latter method, and I got this exception :
MapperParsingException[object mapping for [source] tried to parse field [source] as object, but found a concrete value]
I'm using Java 1.8.0.121, and both versions of ElasticSearch and TransportClient are 5.1. Thanks!
The answer is much more easier than I thought.
Gson gson = new Gson();
String sourceJsonString = gson.toJson(updateContent);
UpdateResponse response = client
.prepareUpdate(_index, "logs", id).setDoc(sourceJsonString).get();
updateContent is the object that contained new data, just to transform it to Json string, then use that to update, done.
I have a multi-platform Cordova app backed by a .net web service which returns JSON data for syncing. This works fine.
I am now trying to add native calls into the Android version of the app which are hooked into BroadcastReceiver so that I can provide rich notifications when the app isn't running.
The scheduling and execution of these events are running fine; but I am having real problems in processing the result of the web service call.
The web service call (VB.net) is:
<OperationContract()>
<WebInvoke(Method:="POST", ResponseFormat:=WebMessageFormat.Json)>
Public Function SyncNotifications_Native(ByVal dateAfter As String, ByVal which As Integer, ByVal userID As Int32) As String
Dim rowsList As New List(Of Dictionary(Of String, Object))()
Dim row As Dictionary(Of String, Object)
:::
:::
While dr.Read()
row = New Dictionary(Of String, Object)
row.Add("allow_reply", dr("allow_reply"))
row.Add("content", dr("content"))
row.Add("date_added", dr("date_added")
row.Add("date_deleted", dr("date_deleted")
row.Add("date_read", dr("date_read")
row.Add("deleted", dr("deleted"))
row.Add("last_update", Now().ToString("yyyy-MM-dd HH:mm:ss"))
row.Add("notification_id", dr("notification_id"))
row.Add("subject_line", dr("subject_line"))
row.Add("user_id", dr("user_id"))
rowsList.Add(row)
End While
Return New JavaScriptSerializer().Serialize(details)
End Function
This should return an array of zero or more entries.
I'm using an AsyncTask to get the data. This is the data I get back from the call:
{"d":"
[{\"allow_reply\":1,\"content\":\"test content\",
\"date_added\":\"2016-02-04 23:37:50\",\"date_deleted\":\"\",
\"date_read\":\"\",\"deleted\":0,\"last_update\":\"2016-02-04 23:38:43\",
\"notification_id\":27,\"subject_line\":\"test\",\"user_id\":1}]
"}
I've looked at various resources and have tried all types of solutions. This is what I'm currently doing:
Convert the return string to a JSON Object:
JSONObject json2 = new JSONObject(s);
Try to get the array out of the object:
JSONArray results = json2.getJSONArray("d");
This way gives me an error of:
java.lang.String cannot be converted to JSONArray
I've seen a suggestion in another post that I'm actually returning a SOAP response from my web service; I'm not sure, I haven't seen any other example JSON responses which start with
{"d":
How can I properly get the returned array into a JSONArray so that I can pass it off to another function?
Thanks
Am not a Java dev so:
{"d": "[{\"allow_reply\":1,\....."} is an Object
with a d field
whose value is a string "[{\"allow_reply\":1,\....."} and is why you get java.lang.String cannot be converted to JSONArray
so you'll have to parse (aka "deserialize")
So in Javascript (you'll have to translate to Java):
//this is the data your service returns
var foo = {"d": "[{\"allow_reply\":1,\"content\":\"test content\",\"date_added\":\"2016-02-04 23:37:50\",\"date_deleted\":\"\",\"date_read\":\"\", \"deleted\":0,\"last_update\":\"2016-02-04 23:38:43\",\"notification_id\":27,\"subject_line\":\"test\",\"user_id\":1}]"};
//parse the string
var data = JSON.parse(foo.d);
data now contains your array
So in your code above, you have to parse the string and convert it into the object it represents (from a string).
Hth...
i'm trying to create a dynamic photo gallery which retrieve the photo's location from mySQL. Store the location to a photo object under the name 'private String location;'
There will be an ArrayList to hold all the different photos. After, the servlet will forward to a jsp page
request.setAttribute("list", list);
request.getRequestDispatcher("car.jsp").forward(request, response);
i have a java script for the photo gallery that takes in an array of, ["path_to_image", "optional_link", "optional_linktarget", "optional_textdescription"].
imagearray: [
["path_to_image", "optional_link", "optional_linktarget", "optional_textdescription"],
["a.jpg", "www.a.com", "", ""]
],
I would like to retrieve the location from the object in the list passed in from the servlet and convert it into the imagearray for my photo gallery to work.
I'm quite new to javascript and i've been looking around for similar example or tutorial but i couldn't find any relevant ones. Please help me out, thank you so much for your time.
what i get from your question is photo is an object of a class and location is a member variable of that class.
request.setAttribute("list", list);
request.getRequestDispatcher("car.jsp").forward(request, response);
is this list is a Arraylist of photo object or location member variable.
also you are setting attribute in java and you want that list to hold by javascript.
then in that case you can check JSON for holding your java object and to convert into javascript object.
you will get your string in JSON similar to
{imagearray:[{"path_to_image":"path_to_image","optional_link":"optional_link","optional_linktarget":"optional_linktarget","optional_textdescription"}]}
What you want to do can be simply achieved by the following sequence:
Get results from a database.
Create JSON object.
Set that object as request attribute.
Assign JSON to a JavaScript variable.
Now, let's carry on doing that list.
Get results from database
You should have a method of type getPhotoList() that returns List<Photo>. I suppose that your Photo class has the fields you'd like to export to JavaScript. In the end, you'll have List<Photo> photos initialized.
Create a JSON object
You can of course do that on your own, but a much better idea is to employ a specialized library that converts a java object to a JSON object. For example, you could use Gson library, which is a known library for that type of conversions. In the end, you'll have a JSON object, by calling String photosJSON = new Gson().toJson(photos);.
Set the JSON as a request attribute and perform a forward
Standard operation here.
request.setAttribute("photos", photosJSON);
request.getRequestDispatcher("car.jsp").forward(request, response);
Assign JSON to a JavaScript variable
In your JSP code, within a <script> block, have the following line:
var photosJS = JSON.parse(${photos});
Finally, you'll have a JS variable photosJS with a list you got from the database.
How do I use Rhino return a string from Java to Javascript, all I get is org.mozilla.javascript.JavaNativeObject when I use
var jsString = new java.lang.String("test");
inside my js file.
Is this the right way to do it?
var jsString = String(new java.lang.String("test"));
The goal is to have a Java method to return the String object instead of creating it on the fly like above.
In general, you would call Context.javaToJS which converts a Java object to its closest representation in Javascript. However, for String objects, that function returns the string itself without needing to wrap it. So if you're always returning a string, you don't need to do anything special.
Although in most cases the returned Java String type can be used just like the JS String type within the JS code, it does not have the same methods!
In particular I found it cannot be used in a JS object passed to 'stringify()' as it does not have the toJSON() method.
The only solution I found is to explicitly do the addition of "" in the JS, to convert the Java String to a JS String. I found no way to code the java method to return a good JS string directly... (as Context.javaToJS() doesn't convert a Java String)
Eg:
var jstr = MyJavaObj.methodReturningAString();
JSON.stringify({ "toto":jstr}); // Fails
JSON.stringify({ "toto": ""+jstr}); // OK
Turn off the wrapping of Primitives and then the value returned in your expression will be a JS string:
Context cx = Context.enter();
cx.getWrapFactory().setJavaPrimitiveWrap(false);
For me this is a Rhino bug. The s+"" trick inside JavaScript works, but here's a quick patch to fix it Java-side - after this line in NativeJavaMethod.call()
Object retval = meth.invoke(javaObject, args);
add this check to convert it to a native JavaScript string (ie typeof returns "string" not "object")
if (retval instanceof String) {
return NativeJavaObject.coerceTypeImpl(String.class, retval);
}
This is important otherwise s.replace() calls the Java version so is wrong for eg "h e l l o".replace(" ", "")
https://github.com/mozilla/rhino/issues/638