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))
Related
Is there a way to tell if a form is valid from Java?
Basically, a method that returns true if all input fields constrains are satisfied and false otherwise.
Strangely enough, org.w3c.dom.html.HTMLFormElement doesn't actually have a checkValidity() method.
EDIT:
Even more strangely, the implementation com.sun.webkit.dom.HTMLFormElementImpl does support the method checkValidity(). Unfortunately, the package com.sun.webkit is not accessible directly and thus the method is unavailable.
DOM objects like HTMLFormElement only model structure. They are not capable of executing JavaScript.
However, WebEngine itself does have a JavaScript interpreter, which you can invoke using the executeScript method:
boolean valid = (Boolean) webView.getEngine().executeScript(
"document.forms[0].checkValidity();");
The checkValidity() method is documented here and here.
Cast the form to JSObject
Most HTML Java elements, including HTMLFormElement, can be directly cast to the JavaScript object JSObject. It is then trivial to validate the form.
Example:
JSObject jsObject = (JSObject) form;
boolean valid = (boolean) jsObject.call("checkValidity");
I am taking a JSON file as input for a class and parsing the values using gson through respective data classes.
I want to call a function that takes a String value as an argument.
The string value allowed is decided from the values parsed from JSON file. Can I somehow check for that string value passed to the function at compile-time & give an error at compile-time?
Or If I can allow only certain values in the argument for the function based on the values from JSON
Detailed Explanation of use case:
I am building a SDK in which a the person using sdk inputs json String. The json is standardised and is parsed in my code.
{
"name": "Test",
"objects": [
{
"name": "object1",
"type": "object1"
}
]
}
Here name values and other values may vary based on the input by the developer using it but key remains same. But we need to call a function using the value in objects name parameter.
fun testMethod(objectName:String)
So developer calls the testMethod as testMethod(object1).
I need to validate object1 parameter based on json but is there any way possible restricting the test method parameter to object1 only & give error at compile time if the developer calls testMethod(obj1)
Right now I parse JSON & have checks inside the testMethod()
Sure it's possible to do, but somehow in different way, that you described. First of all, as you already mentioned this behavior could be done easily. For this purpose we have Objects.requireNotNull() or Guava.Preconditions(). At the same way you can define you checking but this will work on runtime only.
To do in compile time, you need to create Annotation Preprocessor. The same, as did in different libraries, and one of them, could be Lombok, with their NotNull and Nullable. Android annotation just provide mark and bound for IDE warning, but in their case they adding NotNull checking and throw exception for every annotation usage during compile time.
It's not an easy way, but it's what you are looking for.
No, it's impossible check it in compiler time. It's string handling, as numeric calculation.
In my app, I convert string to JSON and JSON to string, passing class descriptor. My aim is record JSON string in a text file to load in SQLite database. This code I've run in my desktop computer not in Android.
data class calcDescr (
...
)
val calc = CalcDescr(...)
// toJson: internal Kotlin data to JSON
val content = Gson().toJson(calc)
//==================
// Testing validity
// ================
// fromJson: JSON to internal Kotlin data.
// It needs pass the class descriptor. Uses *Java* token, but it's *Kotlin*
var testModel = Gson().fromJson(content, CalcDescr::class.java)
// toJson: internal Kotlin data to JSON again
var contentAgain = Gson().toJson(testModel)
// shoul be equal!
if (content == contentAgain) println("***ok***")
In my file, I write the variable content in a file
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
Good Afternoon,
So I am trying to Copy some text from a field so I can paste it somewhere else in my test.
public static void validateTestCaseCreated(){
driver.findElement(By.xpath("//*[#id='mainForm:testTitle']")).click();
Action builder;
Actions copy = new Actions(driver);
copy.sendKeys(Keys.CONTROL + "a");
copy.sendKeys(Keys.CONTROL + "c");
builder = copy.build();
builder.perform();
The problem when it reaches line 6 it only sends c, it ignores the CONTROL. So my end result is not copying the text but highlighting the text then entering c.
You could just copy the value from the text field into a variable and store it for use later.
Pull it from the page using your code along with the get attribute method.
String valueInField = driver.findElement(By.xpath("//*[#id='mainForm:testTitle']")).getAttribute("value");
That will grab the text from the field and put it into the variable for later use.
I'm not sure if this is doing fully what you are trying to do, seeing as you are trying to do a crtl+c, but this method is how to grab text using webdriver.
If your field is an input element, maybe you can do something like this instead:
driver.findElement(By.xpath("//*[#id='mainForm:testTitle']")).click().get_attribute("value");
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