2010-10-25 7 views
1

Avec DJ Native Swing, il est possible d'afficher une page Web dans une application Java. Lorsque vous faites cela, il est également possible de communiquer depuis le navigateur vers l'environnement d'exécution java en utilisant le protocole "command". La documentation a un extrait de code qui démontre son usage:DJ Native Swing Problèmes de commande javascript


function sendCommand(command){ 
    var s = 'command://' + encodeURIComponent(command); 

    for(var i = 1; i < arguments.length; s+= '&' + encodeURIComponent(arguments[i++])); 
     window.location = s; 
} 

Comme il semble ici, il semble être une demande régulière GET à une URL en utilisant le protocole de commande au lieu de http. Bien que lorsque je crée et que l'image, la balise de script ou juste et ajax obtiennent la requête il n'y a aucune réponse et le point d'arrêt dans l'exécution de Java n'est pas déclenché.

Je ne veux pas définir le paramètre window.location car je ne souhaite pas quitter la page à laquelle je suis actuellement. Utiliser le lien pour naviguer vers une url de commande fonctionne bien mais il navigue aussi loin de la page courante. La page utilise OpenLayers et dojo. (J'ai aussi essayé dojo.io.script)

Répondre

2

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.