Login
Cerca all'interno di JavaPortal
Help
Home Page Documentazione Forum Progetti Partner Pubblica!
Documentazione > Tutorial > Compilazione AJAX con JSE 6
Modifica Impostazioni
Hide
Best Practices
EJB
Frameworks
Howto
J2EE
J2ME and Wireless
J2SE
JSP e Servlet
Java Application Server
Java IDE/Tools
Java Media
Java Security
Java Sys Admin
Java e XML
Java e SQL
OpenSource Java
Patterns
Repository
Tesi
UML
Web Services
Slide
White Paper di jws.it
project management
Eventi
Groovy

Hai una tesi in Java?
Tesine preparate
per esami?
Pubblica tutto su
JavaPortal!

Scrivi al nostro staff


Project Kenai


Blaise Pascal
È molto più bello sapere qualcosa di tutto, che tutto di una cosa


Come usare una classe java per interagire con xml (seconda parte)


Rss Feed
Home Page
Articoli
News
Forum
Classi

  Visualizza Commenti (0) Aggiungi Commento    
Add to Shortcuts
 
Vota l'articolo
Compilazione AJAX con JSE 6
By Francesco Marchioni
20 marzo 2007
Valutazione Acquisita: 30

  Compilazione AJAX con JSE 6
Program Gli scripting
Program Utilizzare una funzione javascript da Java
Program Compilazione di codice Javascript
Program Mettiamo il tutto in un Task Ant

Questo è il primo di una serie di articoli sulla nuova release della JSE 6, che riguardano il nuovo paradigma delle applicazioni Web 2.0.

E’ noto che, le applicazioni Web di nuova generazione si sono evolute da semplice strumento di navigazione ad applicazioni che gestiscono contenuti “ricchi”, altrimenti chiamate rich client application.

Lo strumento essenziale su cui poggia questa nuova tecnologia non è un nuovo linguaggio, bensì una tecnica che combina l’uso di tecnologie e tecniche  già esistenti come javascript, XML,DHTML,CSS.
La tecnica è stata denominata AJAX, racchiudendo in questo acronimo la definizione di Asynchronous JavaScript and XML.

AJAX utilizza un trasferimento asincrono tra il browser e il web server, permettendo alle pagine web di richiedere al server poche informazioni per volta, invece di intere pagine HTML.
Questa tecnologia rende le applicazioni internet più piccole, più veloci e decisamente più user friendly.

Che collegamento ci può essere tra AJAX e la nuova versione di Java ?
E’ presto detto. Una delle  novità della nuova release di Java è l’adozione della  JSR 223: Scripting for the JavaTM Platform  che aggiunge a Mustang (nome scelto per la J2SE 6) il supporto per integrare il linguaggio Java con i linguaggi di scripting (come PHP o Ruby, non solo JavaScript).



Gli scripting top

La prima funzionalità che possiamo verificare è la disponibilità di Scripting Engine disponibili con la release attuale della JDK.

La classe principale, inserita nel namespace javax.script, è ScriptEngineManager.
Questa classe fornisce alla factory (ScriptEngineFactory) un discovery mechanism  che consente di accedere all’ Engine di Scripting.

Nel seguente esempio, viene evidenziata la relazione che esiste tra queste classi, stampando a video informazioni sulle factory che vengono trovate. Per adesso ci limitiamo a stampare informazioni sulle factory, mentre non viene eseguita ancora nessuna operazione con l’Engine di scripting.


Listing 1. Stampa delle factory disponibili sulla Console

import javax.script.*;
import java.io.*;
import java.util.*;
public class ListaEngines  {
public static void main(String args[]) {
ScriptEngineManager manager = new ScriptEngineManager();
List<ScriptEngineFactory> factories = manager.getEngineFactories();

for (ScriptEngineFactory factory: factories) {
Console console = System.console();
console.printf("Name: %s%n" +
"Version: %s%n" +
"Language name: %s%n" +
"Language version: %s%n" +
"Extensions: %s%n" +
"Mime types: %s%n" +
"Names: %s%n",
factory.getEngineName(),
factory.getEngineVersion(),
factory.getLanguageName(),
factory.getLanguageVersion(),
factory.getExtensions(),
factory.getMimeTypes(),
factory.getNames());

ScriptEngine engine = factory.getScriptEngine();
}
 }
}


java ListEngines

Name: Mozilla Rhino
Version: 1.6 release 2
Language name: ECMAScript
Language version: 1.6
Extensions: [js]
Mime types: [application/javascript, application/ecmascript, text/javascript,
text/ecmascript]
Names: [js, rhino, JavaScript, javascript, ECMAScript, ecmascript]


Come visualizzabile da questo esempio, è presente per ora soltanto la versione 1.6 di Mozilla Rhino. Per il nostro esempio è sufficiente.

Da notare nell’esempio: la classe System ha un nuovo metodo, console() che restituisce un’istanza della classe Console (inserita nel package java.io). Questa classe funziona in combinazione con i flussi Reader e Writer per catturare i flussi di lettura e scrittura inviati dalla console, ed è compatibile con gli high-order byte characters.
Altra aggiunta meritevole di nota è la printf che permette di formattare l’input della console in modo analogo al C.

Listing 2. Stampa utilizzando il metodo printf

public class Stampa {
public static void main(String args[]) {
  String string = "adesso stampo correttamente gli accenti: àèìòù";
  System.out.println(string);
  System.console().printf("%s%n", string);
}
}




Utilizzare una funzione javascript da Java top

Nell’esempio successivo, andiamo ad utilizzare una prima funzionalità offerta dagli ScriptEngine, cioè andremo a richiamare il metodo eval.

Come è visibile nella documentazione fornita dalla Sun, questa interfaccia fornisce una serie di implementazioni del metodo eval, a seconda se lo script su cui andiamo ad operare viene letto da uno stream a caratteri (Interfaccia Reader), oppure da una semplice stringa di caratteri contenenti il codice Javascript.

Nel nostro esempio, andremo proprio ad utilizzare una semplice stringa di caratteri per eseguire una funzione javascript molto semplice, come l’arrotondamento di un numero di 3 cifre decimali.

Listing 3. Arrontoda.java

import javax.script.*;
import java.io.*;

public class Arrotonda {

public static void main(String args[]) {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("javascript");
    if (args.length != 1) {
    System.err.println("Inserisci un numero con tre cifre decimali");
    System.exit(-1);
    }
    try {
    engine.put("n", args[0]);
    engine.eval(
    "var output = '';" +    
    " n = Math.round(n * 100) / 100;"+
        " n = (n + 0.001) + '';" +
        " output = n.substring(0, n.indexOf('.') + 3);");

    String value = (String)engine.get("output");
    Console console = System.console();
    console.printf("Numero arrotondato: %s%n", value);
    } catch (ScriptException e) {
    System.err.println(e);
    }
}
}


java Arrontonda 7654.119

Numero arrotondato: 7654.120



Com’e’ facilmente intuibile, l’engine di javascript permette il passaggio di variabili (l’equivalente degli argomenti delle funzioni) mediante engine.put( ), che nel nostro caso trasferisce nella variabile ‘n’ l’argomento [0] del main.

Gli argomenti di ritorno possono essere letti mediante il metodo get, che restituisce il valore della variabile “output” che è stata valorizzata nella funzione javascript.

String value = (String)engine.get("output");



Compilazione di codice Javascript top

Vediamo adesso come eseguire una prova di compilazione di un codice javascript più complesso.

Listing 4. CompileAjax.java

import javax.script.*;
import java.io.*;
public class CompileAjax {
    
    static String readFile(String fileName) {
        StringBuffer sb = new StringBuffer();
       
        try {
            BufferedReader in = new BufferedReader(new FileReader(fileName));
            String line;
            while((line = in.readLine()) != null) { 
                sb.append(line);             
                sb.append("\n");
            }
            in.close();   
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
   
    public void compile(String fileName) {
        System.out.println("Compilazione ..........."+fileName);   
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");

        if (engine instanceof Compilable) {
            Compilable compEngine = (Compilable)engine;
           
            String file = readFile(fileName);
           
            try {
                CompiledScript script = compEngine.compile(file);
               
                Console console = System.console();
                Object obj = script.eval();
               
                if (obj == null) {
                    console.printf("Compilazione terminata con successo");
                }   
               
            } catch (ScriptException e) {
                System.err.println(e);
            }
        } else {
            System.err.println("Errore di compilazione !");
        }
    }
   
    public static void main(String args[]) {
        new CompileAjax ().compile("ajax.js");
       
    }
}


Abbiamo inserito all’interno della classe CompileAjax il metodo compile, che prende in ingresso il file JavaScript da compilare.

Il file Javascript viene elencato in seguito (ajax.js).
Al suo interno sono presenti delle funzioni che utilizzando la XMLHttpRequest per comunicare con una Servlet (la servlet è mappata con l’URI  “/getStockPrice”).

Listing 5. ajax.js

var request;
var symbol;  // Titolo di cui si chiede la quotazione

function httpRequest(reqType,url,asynch){
    //Inizializza la request in base al browser
    //utilizzato
    if(window.XMLHttpRequest){
        request = new XMLHttpRequest(  );
    } else if (window.ActiveXObject){
        request=new ActiveXObject("Msxml2.XMLHTTP");
        if (! request){
            request=new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    //Controlla se la request è stata inizializzata
    if(request){
        initReq(reqType,url,asynch);
    } else {
        alert("Il tuo browser non suppporta Ajax. Aggiornare ad un browser più recente!");
    }
}

/* Metodo che fa partire la request verso il server */

function initReq(reqType,url,bool){
    request.onreadystatechange=handleResponse;
    request.open(reqType,url,bool);
    request.send(null);
}

function getStockPrice(sym){
    symbol=sym;
    if(sym){
        var url="/getStockPrice?sym="+sym;
        httpRequest("GET",url,true); 
    }
}

/* Questa è la funzione di callback per la XMLHttpRequest */

function handleResponse(  ){
    if(request.readyState == 4){
        if(request.status == 200){
            /* Valore di ritorno dalla Servlet */
            var stockPrice = request.responseText;
           
            document.getElementById("stPrice").style.fontSize="0.9em";
            document.getElementById("stPrice").style.backgroundColor="yellow";
            document.getElementById("stPrice").innerHTML="&nbsp;Prezzo del titolo: " +stockPrice;
           
        } else {
            alert("Problema di comunicazione con il server.”);
        }
    }
  }

}

Per completezza includiamo il codice della Servlet, che esegue l’accesso ad una base dati per leggere il valore del titolo richiesto. Scrivendo nello stream della response vengono passati i dati alla nostra servlet.


Listing 6. AjaxServlet.java

package demoajax;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;


public class AjaxServlet extends HttpServlet {


  public void init(ServletConfig config) throws ServletException {
    super.init(config);
  }


  public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
    
    response.setContentType("text/html");
   
    String stockName = request.getParameter("sym");

    // Prende la quotazione dal Database
   
    String quote = StockManager.getQuote(stockName);

    // Ritorna ad Ajax il valore del titolo
    PrintWriter out = new PrintWriter (response.getOutputStream());
      
    out.println(quote);
    out.close();    
  }


  public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
    doGet(request,response);
  }

}


Analizzando adesso la classe CompileAjax, ci rendiamo conto che quello che è stato aggiunto rispetto all’esempio precedente (Listing 3. Arrontoda.java) è soltanto l’utilizzo dell’interfaccia Compilable che viene utilizzata per fare il cast dell’ Engine javascript.

Compilable compEngine = (Compilable)engine;

Adesso, è possibile eseguire la compilazione vera e propria, usando il metodo compile che restituisce un oggetto di tipo CompiledScript

CompiledScript script = compEngine.compile(file);

Nel caso del nostro script, la compilazione termina con successo.

Proviamo adesso ad eseguire una modifica alle prime due righe del nostro file ajax.js

var request;
var symbol;  // Titolo di cui si chiede la quotazione


Supponiamo che per errore il commento sia stato accidentalmente cancellato, quindi sostituiamo il blocco con

var request;
var symbol;   Titolo di cui si chiede la quotazione



Quello che otteniamo dalla compilazione è:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: missing ; before statement (<Unknown Source>#2)

Com’e’ visibile, il risultato è un’eccezione di tipo ScriptException che contiene il numero di riga dove si è verificata l’eccezione (<Unknown Source>#2).

Le possibilità di utilizzo di questa funzionalità sono molteplici, ad esempio è possibile costruirsi un semplice Text editor che validi il codice javascript, segnalando la riga dove si è verificato l’errore.
 

Mettiamo il tutto in un Task Ant top

Ora,  utilizziamo lo stesso codice di esempio per creare un Custom Ant Task che vada a compilare tutti i files javascript presenti all’interno di un FileSet.

Diamo per scontato che il lettore abbia una conoscenza di Ant , comunque ricordiamo che per creare un proprio Task in Ant, occorre estendere l’interfaccia org.apache.tools.ant.Task ed implementare il metodo execute(,) dove viene svolto il Task vero e proprio.
Per approfondimenti su Ant, si possono consultare le slide presenti nel portale, cioè Presentazione Ant .

Per poter interagire con il Task, è necessario ricreare l’elenco dei parametri del nostro Task mediante i classici metodi getter/setter. Nell’ esempio da noi implementato però, non passeremo dei parametri ma un Fileset, ovvero una struttura di directories , su cui andremo ad eseguire la scansione.

Perciò, l’unica differenza, rispetto all’uso dei parametri, è l’utilizzo del metodo addFileSet(FileSet fileset) al posto dei getters/setters per inizializzare i parametri di ingresso del nostro Task.

Listing 7. AjaxPrecompiler.java


package compileAjax;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

import org.apache.tools.ant.types.*;
import org.apache.tools.ant.DirectoryScanner;

import java.io.*;
import java.util.*;


public class AjaxPrecompiler extends Task {

   String extension = null;
   Vector<FileSet> filesets = new Vector<FileSet>();

   /* Questo è il metodo setter per valorizzare il Fileset */

   public void addFileSet(FileSet fileset) {
      if (!filesets.contains(fileset)) {
         filesets.add(fileset);
      }
   }


   public void execute() {
      /* Richiama la nostra classe che Compila il
         fileset */
      CompileAjax compileTest = new CompileAjax ();
      
        int filesProcessed = 0;
           DirectoryScanner ds;
      for (FileSet fileset : filesets) {
         ds = fileset.getDirectoryScanner(getProject());
         File dir = ds.getBasedir();

        
         String[] filesInSet = ds.getIncludedFiles();
         for (String filename : filesInSet) {
            File file = new File(dir,filename);
            compileTest.compile(file.getName());
            System.out.println("File is "+file.getName());
           
            filesProcessed++;
         }
      }
      log("Done. "+filesProcessed+" file(s) compilati.");
   }

  
}

Per utilizzare il Task all’interno del file build.xml, è sufficiente inserire il Task all’ interno di un file jar, che poi referenzieremo nel relativo file build.xml

jar cvf ajax.jar compile

si crea : ajax.jar

Questo è il file build.xml di ant che andremo a creare:

Listing 8. build.xml

<project name="CompilaAjaxTask" default="main" basedir=".">
  <taskdef name="AjaxCompiler" classpath="ajax.jar" classname="compileAjax.AjaxPrecompiler" />

  <target name="main">   
    <mytask>
             <fileset dir="${basedir}" includes="*.js"/>
    </mytask>
  </target>
</project>


Per eseguire il nostro file ant:

Listing 9. ant.cmd


SET LOCALCLASSPATH=%CLASSPATH%;%ANT_HOME%\lib\ant.jar
SET LOCALCLASSPATH=%LOCALCLASSPATH%;c:\jdk1.5\lib\tools.jar
SET LOCALCLASSPATH=%LOCALCLASSPATH%; ajax.jar

java -classpath %LOCALCLASSPATH%  org.apache.tools.ant.Main %1 %2 %3 %4 %5

 

Username:
Password:
To sign up for an account, click register... Register
Hide





Powered By



Campagna Anti-IF


Skin


PARTNER
Zio Budda
HostingJava


LICENZA



Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons

Sitemap  © 2002-2004 Copyright Information. Privacy . Today is domenica 1 agosto 2010