Calling Java Methods in JavaScript Code

calling java methods in javascript code

When it is on server side, use web services - maybe RESTful with JSON.

  • create a web service (for example with Tomcat)
  • call its URL from JavaScript (for example with JQuery or dojo)

When Java code is in applet you can use JavaScript bridge. The bridge between the Java and JavaScript programming languages, known informally as LiveConnect, is implemented in Java plugin. Formerly Mozilla-specific LiveConnect functionality, such as the ability to call static Java methods, instantiate new Java objects and reference third-party packages from JavaScript, is now available in all browsers.

Below is example from documentation. Look at methodReturningString.

Java code:

public class MethodInvocation extends Applet {
public void noArgMethod() { ... }
public void someMethod(String arg) { ... }
public void someMethod(int arg) { ... }
public int methodReturningInt() { return 5; }
public String methodReturningString() { return "Hello"; }
public OtherClass methodReturningObject() { return new OtherClass(); }
}

public class OtherClass {
public void anotherMethod();
}

Web page and JavaScript code:

<applet id="app"
archive="examples.jar"
code="MethodInvocation" ...>
</applet>
<script language="javascript">
app.noArgMethod();
app.someMethod("Hello");
app.someMethod(5);
var five = app.methodReturningInt();
var hello = app.methodReturningString();
app.methodReturningObject().anotherMethod();
</script>

Call external javascript functions from java code

Use ScriptEngine.eval(java.io.Reader) to read the script

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
// read script file
engine.eval(Files.newBufferedReader(Paths.get("C:/Scripts/Jsfunctions.js"), StandardCharsets.UTF_8));

Invocable inv = (Invocable) engine;
// call function from script file
inv.invokeFunction("yourFunction", "param");

How to call Java method from Javascript (Non-server)

The JavaScript engine was changed in Java 8 from the old Rhino to the new Nashorn, and the way to create Java objects was changed.

A generic way that should work in both, would be to pass a Java object to the script using the Bindings. The JavaScript code can then call any public method of that object.

Alternative, pass it in as a parameter.

EXAMPLE using Bindings

ArrayList<String> myList = new ArrayList<>();
myList.add("Hello");

Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("myList", myList);

String script1 = "function hello(name) {" +
" myList.add(name);" +
" print(myList);" +
"}";
engine.eval(script1);

Invocable inv = (Invocable)engine;
inv.invokeFunction("hello", "Scripting!!" );

EXAMPLE using parameter

String script1 = "function hello(myList, name) {" +
" myList.add(name);" +
" print(myList);" +
"}";
engine.eval(script1);

ArrayList<String> myList = new ArrayList<>();
myList.add("Hello");

Invocable inv = (Invocable)engine;
inv.invokeFunction("hello", myList, "Scripting!!");

OUTPUT

[Hello, Scripting!!]

Calling Java method from JSNI

From Accessing Java Methods and Fields from JavaScript documentation:

The syntax is:

[instance-expr.]@class-name::method-name(param-signature)(arguments)
  • instance-expr. : must be present when calling an instance method and must be absent when calling a static method

  • class-name : is the fully-qualified name of the class in which the method is declared (or a subclass thereof)

  • param-signature : is the internal Java method signature as specified at JNI Type Signatures but without the trailing signature of
    the method return type since it is not needed to choose the overload

  • arguments : is the actual argument list to pass to the called method

Here are JNI Type Signatures:

Type Signature               Java Type
Z boolean
B byte
C char
S short
I int
J long
F float
D double
L fully-qualified-class ; fully-qualified-class
[ type type[]
( arg-types ) ret-type method type

For example, the Java method:

long f (int n, String s, int[] arr);
has the following type signature:

(ILjava/lang/String;[I)J

In your case (no parameters) it would be:

public native void someMethod (Person person) /*-{
person.@your.package.name.client.Person::sayName()();
}-*/;

Replace your.package.name with a real package name.

How to call Java function dynamically from Javascript?

When you display that page, the JSP is executed once on the server, which means that t.getTime() is executed once.

If you do a "View Source" in the web browser, you'll see that the server has generated the following:

<script type="text/javascript">

var time="";
function showTime(){
time = '2020/03/03 17:47:45';
}
function startTime() {
showTime();
document.getElementById('time').innerHTML =time;
t = setInterval(function () {
startTime()
}, 500);
}
</script>

As you can see, the value of time is now fixed at the date/time the server processed the JSP. Calling showTime() repeatedly will not change the value of time.

If you want the time value to be "live", you need to do this in JavaScript code, not JSP code.

Here is a way to do it, based on this answer to question "Format JavaScript date as yyyy-mm-dd":

    function showTime() {
const date = Date.now();
time = new Date(date.getTime() - date.getTimezoneOffset() * 60000)
.toISOString() // yyyy-MM-ddTHH:mm:ss.SSSZ
.replace(/\..*/, '') // yyyy-MM-ddTHH:mm:ss
.replace(/T/, ' ') // yyyy-MM-dd HH:mm:ss
.replace(/-/g, '/'); // yyyy/MM/dd HH:mm:ss
}

Call a Java method from Javascript

Your question involves multiple technologies. I will try to give you some direction towards all of them in steps.

When you write a Java class, it is deployed on the server side. When you write a JavaScript function, it is deployed on the client side.

The server side Java classes may be deployed as a web application in an application server (Apache tomcat for example), and exposed over a URL. The interface for doing so is to write what is known as a Servlet. A servlet is nothing but another Java class deployed on the same application server. This servlet class can invoke your Java method. (Note: There are other technologies (JSP or Java Server Pages, for example) which eventually get re-engineered to a servlet.)

There is abundant literature on how servlets work, but in short, once deployed in an application server, the code inside the servlet can be invoked when the application URL is invoked from a browser.

So, here are the steps:

  1. You invoke a URL from your browser for the application deployed on the application server. For example, you invoke http://localhost:8080/myapp/doSomething
  2. Your web application (myapp) has a deployment descriptor (web.xml) with its own URL mapping. By referencing this descriptor, your webapp realizes that for the URL: "/doSomething" it should invoke MyServlet (your servlet deployed on the server)
  3. Your servlet (MyServlet) will now implement some of the standard doXXX methods (for GET, POST, etc. operation).
  4. Within this implementation of the doXXX method, you can invoke your Java class method.
  5. Once your servlet completes execution, it writes a response to the servlet's output stream, which the application server then streams back to your browser over http. Now, within your response, you can choose to write anything you want - this is what will be available to you on the browser when you invoke the URL.

Having said the above steps, from JavaScript, you can invoke a URL and get a response using technologies like AJAX.

If your function does not return a value, but simply "does something", then you really do not care about the response, However, using AJAX, you can also check the status on the response to see if there were any exceptions that occurred while executing your function on the server side.

Calling a Java Function From JavaScript Code?

Usually, javascript runs on browser and Java class runs in your servlet container. You can implement your logic by javascript and data operation by java. Jquery will help you to use ajax easily.

out.println("<script type=\"text/javascript\" src=\"http://code.jquery.com/jquery-1.10.0.min.js\"></script>");
out.println("<script type='text/javascript'>");
out.println("result = confirm(Do you wanna to record in DB?)");
out.println("if(result) {");
out.println(" alert('will record');");
out.println("$.ajax({" +
"type: \"POST\"," +
"url: \"/your_servlet_url\"," +
"data: \"action=record\"," +
"success: function(msg) {" +
" alert( \"Data Saved: \" + msg );" +
"}" +
"});");
out.println("} else {");
out.println(" alert('will not record');");
out.println("$.ajax({" +
"type: \"POST\"," +
"url: \"/your_servlet_url\"," +
"data: \"action=norecord\"," +
"success: function(msg) {" +
" alert( \"Data Saved: \" + msg );" +
"}" +
"});");
out.println("}");
out.println("</script>");
out.flush();

Then you need to get what the parameter action value is and do what you want in your servlet.



Related Topics



Leave a reply



Submit