Java 应用程序和网页中的 Javascript 之间的通信
当使用 WebView 显示你自己的自定义网页并且此网页包含 Javascript 时,可能需要在 Java 程序和网页中的 Javascript 之间建立双向通信。
此示例显示如何设置此类通信。
网页应显示输入字段和按钮。单击该按钮时,输入字段中的值将发送到 Java 应用程序,Java 应用程序将对其进行处理。在处理之后,结果被发送到 Javascript,Javascript 又在网页上显示结果。
基本原则是,对于从 Javascript 到 Java 的通信,在 Java 中创建一个对象,该对象被设置到网页中。而对于另一个方向,在 Javascript 中创建一个对象并从网页中提取。
以下代码显示了 Java 部分,我将它保存在一个文件中:
package com.sothawo.test;
import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
import java.io.File;
import java.net.URL;
/**
* @author P.J. Meisch (pj.meisch@sothawo.com).
*/
public class WebViewApplication extends Application {
/** for communication to the Javascript engine. */
private JSObject javascriptConnector;
/** for communication from the Javascript engine. */
private JavaConnector javaConnector = new JavaConnector();;
@Override
public void start(Stage primaryStage) throws Exception {
URL url = new File("./js-sample.html").toURI().toURL();
WebView webView = new WebView();
final WebEngine webEngine = webView.getEngine();
// set up the listener
webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
if (Worker.State.SUCCEEDED == newValue) {
// set an interface object named 'javaConnector' in the web engine's page
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("javaConnector", javaConnector);
// get the Javascript connector object.
javascriptConnector = (JSObject) webEngine.executeScript("getJsConnector()");
}
});
Scene scene = new Scene(webView, 300, 150);
primaryStage.setScene(scene);
primaryStage.show();
// now load the page
webEngine.load(url.toString());
}
public class JavaConnector {
/**
* called when the JS side wants a String to be converted.
*
* @param value
* the String to convert
*/
public void toLowerCase(String value) {
if (null != value) {
javascriptConnector.call("showResult", value.toLowerCase());
}
}
}
}
加载页面后,通过以下调用将 JavaConnector
对象(由内部类定义并创建为字段)设置到网页中:
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("javaConnector", javaConnector);
用网页检索 javascriptConnector
对象
javascriptConnector = (JSObject) webEngine.executeScript("getJsConnector()");
当调用 JavaConnector
的 toLowerCase(String)
方法时,转换传入的值,然后通过 javascriptConnector
对象发回。
这是 html 和 javascript 代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body>
<main>
<div><input id="input" type="text"></div>
<button onclick="sendToJava();">to lower case</button>
<div id="result"></div>
</main>
<script type="text/javascript">
function sendToJava () {
var s = document.getElementById('input').value;
javaConnector.toLowerCase(s);
};
var jsConnector = {
showResult: function (result) {
document.getElementById('result').innerHTML = result;
}
};
function getJsConnector() {
return jsConnector;
};
</script>
</body>
</html>
sendToJava
函数调用由 Java 代码设置的 JavaConnector
的方法:
function sendToJava () {
var s = document.getElementById('input').value;
javaConnector.toLowerCase(s);
};
并且 Java 代码调用以检索 javascriptConnector
的函数只返回 jsConnector
对象:
var jsConnector = {
showResult: function (result) {
document.getElementById('result').innerHTML = result;
}
};
function getJsConnector() {
return jsConnector;
};
Java 和 Javascript 之间的调用的参数类型不仅限于字符串。有关可能的类型和转换的更多信息,请参阅 JSObject API 文档 。