Un’introduzione alle JSP (Java Server Pages)

Inizia con questo articolo una serie su JSP, con il quale avremo modo di vedere come funziona questa tecnologia e come possiamo usarla nello sviluppo di siti Web.

Introduzione

JSP è l’abbreviazione di Java Server Pages ed è una tecnologia della SUN che permette di creare contenuti dinamici sul nostro sito. Prima di tutto facciamo un’attimo di chiarezza su siti statici e siti dinamici. Un sito statico contiene una serie di pagine (HTML, XHTML, WML et similia) che hanno una struttura predefinita e che sono collegate tra loro con semplici
collegamenti ipertestuali.

Un sito dinamico invece permette di generare le pagine in maniera dinamica, per esempio in base all’input dell’utente o a notizie che vengono pubblicate su altri siti. Le tecnologie che permettono di creare siti dinamici sono molte, come PHP, ASP e tanti altri. L’antenato di tutti questi linguaggi di scripting è una tecnologia, le CGI (Common Gateway Interface). Queste infatti furono il primo standard che ha permesso di definire dei veri e propri programmi che potevano interagire con l’utente sulla base della richiesta che lui inviava.

In questo modo si potevano creare le prime pagine dinamiche. Tutto ciò non ha niente a che vedere con la semplicità e con la vasta gamma di funzionalità che oggi i linguaggi di scripting lato server hanno. JSP è la risposta della SUN a queste tecnologie. La tecnologia JSP è arrivata attualmente alla versione 2.1, per maggiori informazioni sulla specifica di questa ultima versione consiglio di andare al seguente url http://jcp.org/en/jsr/detail?id=245 .

Senza addentrarci ora in discussioni sulla tecnologia, che a questo punto non sarebbero molto utili, cerchiamo invece di capire che cos’è e come funziona una pagina JSP. Prima però dobbiamo capire la tecnologia della SUN sulla quale essa è basata, ovvero le Servlet.

Java Servlet

Le Java Servlet sono state create prendendo spunto dalle CGI e hanno quindi un funzionamento simile ma con una maggiore performance, semplicità e potenzialità di sviluppo.

Il funzionamento delle Servlet è abbastanza semplice. Quando noi richiediamo una pagina ad un WebServer con il nostro browser inviamo una richiesta conforme al protocollo HTTP, che specifica al WebServer la pagina richiesta e altre informazioni. Il WebServer nel caso di pagine statiche non fa altro che prendere dal suo filesystem il file e inviarcelo con una risposta.

Nel caso di pagine dinamiche, o comunque di programmi che creano pagine dinamiche, il WebServer dovrà prima eseguire un programma e il risultato sarà la risposta che il client riceverà. Le Servlet non sono altro che una possibile implementazione in Java di questo funzionamento. In base ad un richiesta HTTP che viene fatta da un client viene passata questa informazione alla Servlet, ovvero una classe Java.

Questa particolare classe riceve dal Servlet Container (ovvero un WebServer che permette appunto di avere il supporto alle Servlet) la richiesta che è stata effettuata. In base ad una certa funzionalità che questa Servlet dovrà espletare, viene costruita la risposta che viene poi inviata al client.

Le Servlet quindi permettono ad un programmatore Java di realizzare in maniera abbastanza semplice delle pagine dinamiche. Il problema è che quando dobbiamo scrivere codice HTML nella risposta questo è immerso nel codice della classe, quindi la lettura di questa classe o comunque la modifica risulta ad un certo punto molto laborioso come il seguente esempio

protected void doGet(HttpServletRequest request, 
    HttpServletResponse response) throws ServletException, 
    IOException {
	response.setContentType("text/html");
	PrintWriter out = response.getWriter();
	out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet Page</title>");
            out.println("</head>");
            out.println("<body>Ciao");
            out.println("</body>");
            out.println("</html>");
	out.close();
}

Inoltre c’è da considerare il fatto che il layout di un sito può anche non cambiare per molto tempo, mentre le funzionalità che vengono offerte possono aumentare e quindi ogni volta dovremmo riscrivere porzioni di codice nel quale manipoliamo anche l’HTML.

Le Servlet sono comode in altre circostanze, quando devono implementare una qualche logica applicativa che si slega dal produrre tutto l’output della pagina HTML. La classica Servlet che possiamo vedere come HelloWorld ha definiti due principali metodi, doGet() e doPost(), che servono appunto per ricevere le richieste HTTP GET e HTTP POST che vengono fatte e gestirle.

Esempi di codice come il precedente possono far intuire che quando dovremo trattare il layout di un sito abbastanza complesso la manutenzione del codice potrebbe essere un compito assai arduo. Proprio per questo sono state create le JSP.

JSP  (Java Server Pages)

Le JSP sono una tecnologia che si basa sulle Servlet e che si rifà ai più famosi linguaggi lato server per la creazione di siti dinamici come PHP e ASP. In una classica pagina JSP abbiamo il codice HTML all’interno del quale troviamo immerso il linguaggio. Questa è la situazione inversa alle Servlet, dove invece abbiamo il codice HTML immerso nel linguaggio Java. Ecco quindi di seguito riportata una prima pagina JSP d’esempio.

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<html>
    <head><title>JSP Page</title></head>
    <body>
        <%
	int a=1;
	int b=2;
	int c=a+b;
	out.println("Ciao");
         %>
    </body>
</html>

Come potete osservare ci sono delle parti di questa pagina JSP che sono delle semplici porzioni di codice HTML. Queste porzioni possiamo chiamarle template, infatti la loro funzione è proprio quella, ovvero di fare da template alla nostra applicazione JSP, con diversi elementi grafici che magari devono essere ripetuti all’interno di ogni pagina (un banner in alto, un disclaimer, il copyright in basso etc. etc.).

Oltre al semplice HTML ci saranno sicuramente dei tag che non riconoscete. Quelli non sono tag HTML, ma JSP, ovvero dei tag che svolgono una specifica funzione all’interno della nostra web application. Come già detto in precedenza le JSP si basano sulla tecnologia delle Servlet, ovvero quando noi richiamiamo una pagina il Container JSP andrà a leggere la pagina e successivamente tradurrà questa JSP in una Servlet.

Dopo aver generato la Servlet corrispondente, questa sarà compilata, eseguita ed infine il risultato dell’esecuzione della Servlet sarà passato come risposta al client. Potete trovare questo schema di funzionamento rappresentato nella figura seguente.

Flusso richiesta JSP

Flusso richiesta JSP

A questo punto viene subito da chiedersi “Come viene tradotta la JSP in una Servlet?” e soprattutto “Questa fase di traduzione/compilazione/esecuzione non rallenta l’interazione con l’utente?”.

Per quanto riguarda la prima domanda abbiamo già visto che Servlet e JSP sono due tecnologie che possono svolgere i medesimi ruoli, ma chiaramente con pregi e difetti differenti. La Servlet che viene creata dal Container JSP/Servlet avrà riportato a livello di codice Java tutto quello che noi richiamiamo utilizzando i tag delle JSP e per quanto il codice HTML sarà semplicemente immerso nel codice Java. Qui di seguito trovate la traduzione che viene effettuata quando il container JSP legge la nostra JSP d’esempio

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;

public class primoesempio_jsp extends HttpJspBase {

  private static java.util.Vector _jspx_includes;

  public java.util.List getIncludes() {
    return _jspx_includes;
  }

  public void _jspService(HttpServletRequest request, 
    HttpServletResponse response)
        throws java.io.IOException, ServletException {

    JspFactory _jspxFactory = null;
    javax.servlet.jsp.PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;

    try {
      _jspxFactory = JspFactory.getDefaultFactory();
      response.setContentType("text/html;charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, 
          response,null, true, 8192, true);
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("\r\n");
      out.write("<html>\r\n    ");
      out.write("<head>");
      out.write("<title>JSP Page");
      out.write("</title>");
      out.write("</head>\r\n    ");
      out.write("<body>\r\n        ");

	int a=1;
	int b=2;
	int c=a+b;
	out.println("Ciao");

      out.write("\r\n    ");
      out.write("</body>\r\n");
      out.write("</html>\r\n");
    } catch (Throwable t) {
      out = _jspx_out;
      if (out != null && out.getBufferSize() != 0)
        out.clearBuffer();
      if (pageContext != null) 
         pageContext.handlePageException(t);
    } finally {
      if (_jspxFactory != null) 
         _jspxFactory.releasePageContext(pageContext);
    }
  }
}

Non è il massimo della leggibilità ma per fortuna non lo dobbiamo capire noi ma la JVM 🙂

Per quanto riguarda invece la seconda domanda c’è da dire che la Servlet deve essere ricompilata soltanto se la pagina JSP viene modificata. Quindi in una situazione normale avremo soltanto un leggero ritardo quando la pagina JSP verrà richiamata per la prima volta.

Le successive interazioni utilizzeranno la classe che è già stata generata. In una situazione a regime questo non è un problema, esistono comunque dei metodi per effettuare noi direttamente la traduzione della JSP appena facciamo il deploy dell’applicazione.

Specifica JSP

JSP prevede diverse strutture all’interno di una pagina, tutte con uno scopo ben preciso. Partendo dalla pagina JSP d’esempio che abbiamo visto troviamo subito una prima componente, le direttive. Queste servono per specificare appunto delle direttive per la pagina che stiamo scrivendo, come il buffering dell’output, la pagina di errore che si riferisce a questa pagina, includere librerie e file esterni e quant’altro.

Questa è la parte chiaramente meno dinamica di una JSP, ma che serve comunque per poter settare delle informazioni importanti per l’esecuzione della pagina. Poi ci sono quelle che vengono chiamate action, ovvero dei tag che sono utili a svolgere determinate azioni all’interno della nostra pagina JSP. A livello di specifica ne sono definiti diversi, inoltre questi sono ampliati dalle JSTL (Java Standard Tag Library), una libreria che aggiunge appunto ulteriori funzionalità.

In articoli successivi vedremo come poter definire noi delle action attraverso la costruzione di una nostra tag library, cosa che può essere necessaria se gli strumenti a nostra disposizione (action standard e JSTL) non ci soddisfano appieno.

Un altro componente delle pagine JSP è lo scripting, ovvero vere e proprie porzioni di codice Java che possiamo inserire nelle nostre pagine per poter implementare determinate funzionalità. Infine abbiamo l’EL (Expression Language) che è un linguaggio di scripting per niente rigoroso, che ci permette di inserire appunto espressioni dinamiche nella pagina (assegnazione di un valore, semplici calcoli matematici etc. etc.).

Insomma di cose ce ne sono tante da vedere. Per il momento però accontentiamoci di creare l’ambiente di lavoro che utilizzeremo durante il nostro corso e di fare il deploy di una prima JSP d’esempio.

Componenti pagina JSP

Componenti pagina JSP

Tomcat

Abbiamo chiaramente bisogno di testare le pagine JSP e lo faremo utilizzando Tomcat, un JSP/Servlet container opensource della Apache Software Fondation. Prima di tutto dobbiamo installare Tomcat, che possiamo scaricare dal seguente indirizzo http://jakarta.apache.org .

Esistono diverse versioni di Tomcat, noi in questo corso utilizzeremo la versione 4.1.31. Una volta scaricato l’eseguibile lo installiamo e avremo quindi a disposizione il server in una cartella del nostro filesystem. Vediamo quindi da cosa è composto il server.

Nella home directory di Tomcat troviamo diverse sottodirectory. In bin troviamo gli eseguibili per poter avviare e stoppare il server, in conf i file di configurazione, in logs i file di log, in lib le librerie che usa il nostro server, in work le servlet che vengono attualmente utilizzate dal nostro server e in webapps troviamo il posto dove vengono messe le applicazioni delle quali viene fatto il deploy sul server.

Dopo aver installato qualche applicazione tutta questa struttura ci diverrà molto familiare. Ora che abbiamo installato il server facciamolo partire. Eseguiamo il file startup.bat se ci troviamo su un sistema Windows, altrimenti startup.sh se siamo su Linux, che possiamo trovare sotto la cartella bin. In questo modo viene avviato il nostro server.

Per vederlo funzionante possiamo aprire il browser all’indirizzo http://localhost:8080 e ci troveremo davanti la classica pagina che ci comunica che abbiamo appena installato Tomcat. Ora senza entrare troppo nel dettaglio di Tomcat vogliamo installare la nostra prima JSP d’esempio. Prima di fare ciò dobbiamo però capire com’è la struttura di una web application e sopratutto del file che dobbiamo creare per effettuare il deploy, ovvero un WAR (Web Application Archive).

Hello world di Tomcat

Hello world di Tomcat

Deploy

Il WAR rappresenta il file con il quale di solito effettuiamo il deploy delle web application. Questo è molto utile perchè è uno standard e quindi su ogni Container che rispetta le specifiche noi dovremo solamente inserire il nostro WAR, senza modificare la nostra applicazione per ogni server.

Una web application è composta da molti file oltre alle JSP, come file HTML, immagini, video, librerie esterne, JSTL, classi. Insomma tutto quello che abbiamo bisogno per sviluppare una determinata funzione. Il WAR deve quindi avere per forza un’organizzazione, non possiamo buttare alla rinfusa tutti gli elementi della nostra web application e sperare che il server li comprenda.

Partendo dal fatto che rappresenteremo la nostra applicazione come una directory, avremo al livello base tutti i file JSP, HTML, immagini, e quant’altro possa essere incluso staticamente nelle nostre pagine. Poi dobbiamo creare una sottodirectory con il nome di WEB-INF, nella quale mettiamo il file web.xml, il descrittore del deployment. Praticamente in questo file viene spiegato, seguendo una certa sintassi, come verrà mappata la nostra applicazione all’interno del server. Ecco di seguito un esempio.

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>
</web-app>

Ora dobbiamo creare altre due sottodirectory, lib che servirà per le librerie JAR che vogliamo includere nella nostra applicazione e classes che conterrà le classi della nostra applicazione.

In questo primo esempio abbiamo soltanto un file JSP, quindi per vedere la sua esecuzione possiamo semplicemente copiarlo sotto la directory webapps/ROOT/. Nel caso di applicazioni più complesse che vedremo nel seguito del corso dovremo creare un WAR ed effettuare il deploy sotto la cartella webapps di Tomcat.

Ora che abbiamo copiato il nostro file JSP riavviamo il server. Apriamo il browser all’indirizzo http://localhost:8080/primoesempio.jsp e troveremo il risultato dell’esecuzione della nostra pagine JSP. Praticamente Tomcat ha effettuato quei passi che abbiamo prima descritto, ovvero traduzione, compilazione ed esecuzione.

Infatti se andiamo nella cartella work/Standalone/localhost_ troveremo due file che riguardano la nostra JSP, primoesempio_jsp.java (il risultato della traduzione) e primoesempio_jsp.class (il risultato della compilazione).

Conclusioni

Abbiamo visto un primo esempio di pagina JSP e come installarlo su Tomcat. Chiaramente non abbiamo approfondito aspetti essenziali di una pagina JSP, come le direttive, le action e gli script. Nel prossimo articolo inizieremo ad utilizzare questi componenti fondamentali delle JSP, iniziando a creare applicazioni dinamiche interessanti.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.