Après quelques travaux, j'ai trouvé un moyen facile de communiquer avec le runtime java qui ne déclenche pas un rafraîchissement de la page chaque fois qu'il y a une communication. Il est inspiré de la façon dont JSONP fonctionne pour contourner la restriction de domaine croisé dans la plupart des navigateurs de nos jours. Parce qu'un iFrame déclenchera également une action command://
, il est possible de faire une action semblable à JSONP en utilisant cette technique. Le code du côté client (navigateur):
dojo.provide("nmpo.io.java");
dojo.require("dojo.io.script");
nmpo.io.java = dojo.delegate(dojo.io.script, {
attach: function(/*String*/id, /*String*/url, /*Document?*/frameDocument){
// summary:
// creates a new tag pointing to the specified URL and
// adds it to the document.
// description:
// Attaches the script element to the DOM. Use this method if you
// just want to attach a script to the DOM and do not care when or
// if it loads.
var frame = dojo.create("iframe", {
id: id,
frameborder: 0,
framespacing: 0
}, dojo.body());
dojo.style(frame, { display: "none" });
dojo.attr(frame, { src: url });
return frame;
},
_makeScriptDeferred: function(/*Object*/args){
//summary:
// sets up a Deferred object for an IO request.
var dfd = dojo._ioSetArgs(args, this._deferredCancel, this._deferredOk, this._deferredError);
var ioArgs = dfd.ioArgs;
ioArgs.id = dojo._scopeName + "IoScript" + (this._counter++);
ioArgs.canDelete = false;
//Special setup for jsonp case
ioArgs.jsonp = args.callbackParamName || args.jsonp;
if(ioArgs.jsonp){
//Add the jsonp parameter.
ioArgs.query = ioArgs.query || "";
if(ioArgs.query.length > 0){
ioArgs.query += "&";
}
ioArgs.query += ioArgs.jsonp
+ "="
+ (args.frameDoc ? "parent." : "")
+ "nmpo.io.java.jsonp_" + ioArgs.id + "._jsonpCallback";
ioArgs.frameDoc = args.frameDoc;
//Setup the Deferred to have the jsonp callback.
ioArgs.canDelete = true;
dfd._jsonpCallback = this._jsonpCallback;
this["jsonp_" + ioArgs.id] = dfd;
}
return dfd; // dojo.Deferred
}
});
Lorsqu'une demande est envoyée au moteur d'exécution Java un argument de rappel sera fourni et une action webBrowser.executeJavascript(callbackName + "(" + json + ");");
peut être exécutée pour déclencher le rappel dans le navigateur.
Exemple d'utilisation client:
dojo.require("nmpo.io.java");
nmpo.io.java.get({
// For some reason the first paramater (the one after the '?') is never in the
// paramater array in the java runtime. As a work around we stick in a dummy.
url: "command://sum?_",
callbackParamName: "callback",
content: {
numbers: [ 1, 2, 3, 4, 5 ].join(",")
},
load: function(result){
console.log("A result was returned, the sum was [ " + result.result + " ]");
}
});
Exemple d'utilisation java:
webBrowser.addWebBrowserListener(new WebBrowserAdapter() {
@Override
public void commandReceived(WebBrowserCommandEvent e) {
// Check if you have the right command here, left out for the example
// Parse the paramaters into a Hashtable or something, also left out for the example
int sum = 0;
for(String number : arguments.get("numbers").split(",")){
sum += Integer.parseInt(number);
}
// Execute the javascript callback like would happen with a regular JSONP call.
webBrowser.executeJavascript(arguments.get("callback") + "({ result: " + sum + " });");
}
});
également avec IE dans le cadre que je peux recommande fortement d'utiliser Lite Firebug, les outils de dev pour IE ne sont pas disponibles.