Java Tutorial/Trail: Java and Javascript
Java and JavaScript
editJava to JavaScript communication
editThe class netscape.javascript.JSObject
found in the JRE directory in the "lib/plugin.jar" archive is the object that allows communication with the JavaScript engine. The content of the JAR is automatically available inside the Java environment of the web browser. The following code instantiates the JSObject:
public class MyApplet extends Applet {
JSObject window = JSObject.getWindow (this);
}
JSObject
editJSObject
offers the following methods:
java.lang.Object | call (java.lang.String methodName, java.lang.Object[] args) | Calls a method on a JavaScript object. |
java.lang.Object | eval (java.lang.String s) | Evaluates an expression string in JavaScript. |
java.lang.Object | getMember (java.lang.String name) | Returns a named member of a JavaScript object. |
java.lang.Object | getSlot (int index) | Returns an indexed member of a JavaScript object. |
static JSObject | getWindow (java.applet.Applet applet) | Returns a JSObject for the window containing the applet. |
void | removeMember (java.lang.String name) | Removes a named member of a JavaScript object. |
void | setMember (java.lang.String name, java.lang.Object value) | Assigns a named member of a JavaScript object. |
void | setSlot (int index, java.lang.Object value) | Assigns an indexed member of a JavaScript object. |
JavaScript to Java communication
editCalling Java methods from JavaScript is almost too easy, because the Java code exposes all public functions, not just methods intended for communication with the enclosing HTML page. If the applet or object tag has an id of "myApplet" the following code calls into the Java applet:
var myApplet = document.getElementById ("myApplet");
myApplet.publicMethod ();
It is even possible to call methods unrelated to the applet itself with the Packages
keyword:
myApplet.Packages.java.lang.System.out.println ();
Example: Mozilla Persona for Applets
editThis example applet communicates with JavaScript to permit a login to the Mozilla Persona authentication system offered by Mozilla. Discerning readers will notice that the assertion returned by the authentication system could require some sort of verification, which should, for security reasons, not be implemented in the applet. One method of verification is the Remote Verification API.
MozillaPersonaUtil
editpackage org.wikiversity.java_tutorial;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import netscape.javascript.JSException;
import netscape.javascript.JSObject;
public final class MozillaPersonaUtil
{
/**
* onlogin ()<br>
* A user has logged in! Here you need to:<br>
* 1. Send the assertion to your backend for verification and to create a session.<br>
* 2. Update your UI.<br>
* <br>
* onlogout ()<br>
* A user has logged out! Here you need to:<br>
* Tear down the user's session by redirecting the user or making a call to your backend.<br>
*
* @author bernhard
*/
public static class WatchContext
{
String loggedInUser; // The email or null, undefined in case of doubt.
String onlogin; // function(assertion) { ... } (Mandatory)
String onlogout; // function() { ... } (Mandatory)
public String toString ()
{
StringWriter sw = new StringWriter ();
PrintWriter pw = new PrintWriter (sw);
boolean comma = false;
ArrayList<String> list = new ArrayList<String> (3);
if (loggedInUser != null)
list.add ("loggedInUser: '" + loggedInUser + "'");
if (onlogin != null)
list.add ("onlogin: " + onlogin);
if (onlogout != null)
list.add ("onlogout: " + onlogout);
for (String parameter : list)
{
if (!comma)
comma = true;
else
pw.println (',');
pw.print (parameter);
}
pw.println ();
pw.flush ();
return sw.toString ();
}
}
public static class LoginContext
{
String siteName; // My Example Site
String siteLogo; // /logo.png (100x100 pixels)
String termsOfService; // /tos.html
String privacyPolicy; // /privacy.html
String returnTo; // /welcome.html
String onCancel; // function() { alert('user refuses to share identity.'); }
public String toString ()
{
StringWriter sw = new StringWriter ();
PrintWriter pw = new PrintWriter (sw);
boolean comma = false;
ArrayList<String> list = new ArrayList<String> (6);
if (siteName != null)
list.add ("siteName: '" + siteName + "'");
if (siteLogo != null)
list.add ("siteLogo: '" + siteLogo + "'");
if (termsOfService != null)
list.add ("termsOfService: '" + termsOfService + "'");
if (privacyPolicy != null)
list.add ("privacyPolicy: '" + privacyPolicy + "'");
if (returnTo != null)
list.add ("returnTo: '" + returnTo + "'");
if (onCancel != null)
list.add ("oncancel: " + onCancel);
for (String parameter : list)
{
if (!comma)
comma = true;
else
pw.println (',');
pw.print (parameter);
}
pw.println ();
pw.flush ();
return sw.toString ();
}
}
/**
* This method calls navigator.id.request ();
* @see https://developer.mozilla.org/en-US/docs/DOM/navigator.id.request
* @param window
* @param ctx
* @throws JSException
*/
public static void mozillaPersonaLoginRequest (JSObject window, LoginContext ctx)
throws JSException
{
String javaScriptCode = "navigator.id.request ({ " + ctx + " });";
window.eval (javaScriptCode);
}
/**
* This method calls navigator.id.logout ();
* @see https://developer.mozilla.org/en-US/docs/DOM/navigator.id.logout
* @param window
* @throws JSException
*/
public static void mozillaPersonaLogoutRequest (JSObject window)
throws JSException
{
String javaScriptCode = "navigator.id.logout ();";
window.eval (javaScriptCode);
}
/**
* This method calls navigator.id.watch ().
* @see https://developer.mozilla.org/en-US/docs/DOM/navigator.id.watch
* @param window
* @param ctx
* @throws JSException
*/
public static void mozillaPersonaWatch (JSObject window, WatchContext ctx)
throws JSException
{
String javaScriptCode = "navigator.id.watch ({ " + ctx + " });";
window.eval (javaScriptCode);
}
}
MozillaPersonaApplet
editpackage org.wikiversity.java_tutorial;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Method;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import netscape.javascript.JSObject;
import org.w3c.dom.html.HTMLDocument;
public final class MozillaPersonaTestApplet extends JApplet implements ActionListener
{
private final static String PINFO[][] = {
{ "debug", "boolean", "turn on debug information" }
};
@Override
public String[][] getParameterInfo () {
return PINFO;
}
@Override
public void actionPerformed (ActionEvent e)
{
Object src = e.getSource ();
if (src == login)
{
login ();
}
else if (src == logout)
{
logout ();
}
}
private final static String version = "0.5";
private JButton login, logout;
private JTextArea textArea;
@Override
public void init ()
{
login = new JButton ("login");
login.addActionListener (this);
logout = new JButton ("logout");
logout.addActionListener (this);
textArea = new JTextArea ();
textArea.setLineWrap (true);
textArea.setWrapStyleWord (false);
textArea.setText ("[ Version " + version + " ]");
JPanel panel = new JPanel ();
panel.setLayout (new FlowLayout (FlowLayout.LEFT));
panel.add (login);
panel.add (logout);
setLayout (new BorderLayout ());
add (panel, BorderLayout.NORTH);
add (textArea, BorderLayout.CENTER);
}
private boolean debug;
public void callbackLogin (String assertion)
{
textArea.setText ("[callbackLogin] assertion=" + assertion);
}
public void callbackLogout ()
{
textArea.setText ("[callbackLogout]");
}
public void callbackCancel ()
{
textArea.setText ("[callbackCancel]");
}
@Override
public void start ()
{
debug = Boolean.parseBoolean (getParameter ("debug"));
HTMLDocument document = getDocument ();
JSObject window = JSObject.getWindow (this);
MozillaPersonaUtil.WatchContext ctx = new MozillaPersonaUtil.WatchContext ();
ctx.onlogin = "function (assertion) { mozillaPersonaApplet.callbackLogin (assertion); }";
ctx.onlogout = "function () { mozillaPersonaApplet.callbackLogout (); }";
MozillaPersonaUtil.mozillaPersonaWatch (window, ctx);
}
private void login ()
{
JSObject window = JSObject.getWindow (this);
MozillaPersonaUtil.LoginContext ctx = new MozillaPersonaUtil.LoginContext ();
ctx.siteName = "Wikiversity Java Tutorial";
ctx.siteLogo = "/Wikiversity.png";
ctx.privacyPolicy = "/privacypolicy.html";
ctx.termsOfService = "/compliance.html";
ctx.returnTo = "/index.html";
ctx.onCancel = "function () { mozillaPersonaApplet.callbackCancel (); }";
MozillaPersonaUtil.mozillaPersonaLoginRequest (window, ctx);
}
private void logout ()
{
JSObject window = JSObject.getWindow (this);
MozillaPersonaUtil.mozillaPersonaLogoutRequest (window);
}
private HTMLDocument getDocument ()
{
try {
Class c = Class.forName ("com.sun.java.browser.plugin2.DOM");
Method m = c.getMethod ("getDocument", new Class[] { java.applet.Applet.class });
return (HTMLDocument) m.invoke (null, new Object[] { this });
}
catch (Exception e) {
System.out.println ("New Java Plug-In not available");
// In this case, you could fallback to the old bootstrapping
// mechanism available in the com.sun.java.browser.plugin.dom package
return null;
}
}
}