Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Individuare gli errori in una pagina JSP

Tipi di errori e comportamenti dell'Application Server
Tipi di errori e comportamenti dell'Application Server
Link copiato negli appunti

Anche nel mondo JSP, come in quello delle classiche applicazioni Java, ci si trova, non di rado, nella situazione di dover affrontare e risolvere gli immancabili errori che sorgono quando si utilizza una tecnologia potente e complessa come Java. In JSP gli errori più comuni possono essere catalogati in due categorie:

  • HTTP Status 404 – File Not Found Error
  • HTTP Status 500 – Internal Server Error

Errori causati da risorse non disponibili

La prima categoria riguarda gli errori che scaturiscono da situazioni in cui una risorsa richiesta non venga trovata. Se, ad esempio, si utilizza Tomcat come Web Application Server per le nostre pagine JSP, un errore 404 indicherà che Tomcat ha regolarmente ricevuto la richiesta da un client ma non è stato in grado di reperirla e gestirla.

Questo genere di errore, solitamente, si risolve verificando accuratamente che siano stati indicati correttamente sul client il path ed il file relativi alla richiesta e che, nella locazione indicata dalla URL, sia effettivamente presente sul server la risorsa desiderata.

Figura 1. Tipico errore HTTP 404
Tipico errore HTTP 404

Errori di Compilazione

La seconda categoria di errori viene identificata dal server attraverso il messaggio HTTP 500, che corrisponde ad un errore interno del Server (Internal Server Error). A questa categoria appartengono sia gli errori causati da problemi intercorsi durante la compilazione di una pagina JSP sia quelli che si verificano a run-time.

Nel primo caso, il server riceve la richiesta dal client e riesce con successo ad identificare la risorsa associata a tale richiesta. Tenta, quindi, di eseguire la compilazione della pagina in questione ma, a causa di un errore nel codice, fallisce e, pertanto, non riesce ad esaudire la richiesta del client.

Per risolvere questo genere di errori, solitamente è sufficiente esaminare con attenzione il messaggio contenuto nella pagina di errore generata dal Server. Ad esempio, supponiamo di avere la seguente pagina JSP:

Listato 1. Pagina JSP

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Informazioni Utente</title></head>
<body>

<%
  String nome = request.getParameter("nome");
  String cognome = request.getParameter("cognome")
%>

<h1>Dati utente</h1>

<p>Ecco le informazioni relative all'utente inserito:</p>

<table cellspacing="5" cellpadding="5" border="1">
<tr><td align="right">Nome:</td><td><%= nome %></td></tr>
<tr><td align="right">Cognome:</td><td><%= cognome %></td></tr>
<tr><td align="right">Eta':</td><td><%= Integer.parseInt(request.getParameter("eta")) %></td></tr>
</table>

<p>Per inserire un nuovo utente, cliccare sul pulsante "Back"
del browser oppure sul pulsante Nuovo Inserimento in basso.</p>

<form action="addUser.html" method="post">
  <input type="submit" value="Nuovo Inserimento">
</form>

</body>
</html>

Si crei, quindi, una directory a propria scelta sotto la cartella "WebApps" di Tomcat (ad es. "SimpleJSP") e si salvi il codice precedente denominandolo, ad esempio, "show_user.jsp".

Nel codice della pagina JSP, la riga evidenziata in rosso è priva di punto e virgola finale e serve per causare un errore.

A questo punto, per eseguire la nostra pagina JSP, costruiamo, per completezza, una semplice pagina HTML che raccolga i dati in input ed abbia come action la pagina "show_user.jsp" (potremmo, naturalmente, anche invocare la pagina JSP direttamente fornendole i parametri sulla URL).

Listato 2. Pagina HTML con il form

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Inserimento Utente</title></head>
<body>

<h1>Inserimento utente</h1>

<p>Per inserire un utente riempire i campi sottostanti.<br />
Al termine,cliccare sul pulsante Invia.</p>

<form action="show_user.jsp" method="get">

<table cellspacing="5" border="0">
<tr>
  <td align="right">Nome:</td>
  <td><input type="text" name="nome"></td>
</tr>
<tr>
  <td align="right">Cognome:</td>
  <td><input type="text" name="cognome"></td>
</tr>

<tr>
  <td align="right">Eta':</td>
  <td><input type="text" name="eta"></td>
</tr>
<tr>
  <td></td>
  <td><br><input type="submit" value="Invia"></td>
</tr>
</table>

</form>
</body>
</html>

La pagina JSP precendete ci rimanda a questo form se clicchiamo sul pulsante "Nuovo Inseriemnto". Salviamola, quindi, come "addUser.html". Proviamo, adesso ad eseguire il tutto, partendo proprio dalla pagina HTML appena salvata. Digitiamo sul browser l'indirizzo

http://localhost:8080/SimpleJSP/addUser.html

ed inseriamo i dati nel form

Figura 2. Inserimento dati nel form
Inserimento dati nel form

All'invio del form, Tomcat restituirà la seguente pagina di errore:

Figura 3. Pagina di errore in compilazione
Pagina di errore in compilazione

In essa è specificato, chiaramente, che il server ha incontrato un errore alla linea 8 durante la compilazione della pagina e che l'errore stesso è dovuto alla mancanza del punto e virgola al termine di un'istruzione.

Risolto il problema, basterà risalvare il nostro file e ricaricare nuovamente la pagina JSP. Adesso, il risultato sarà quello atteso:

Figura 4. Risultato corretto
Risultato corretto

Errori a Run-Time

Per quanto riguarda gli errori a run time, il risultato visivo è analogo a quello mostrato nella figura precedente; in questi casi verrà evidenziato il punto del codice che ha causato un'eccezione inattesa all'interno della pagina, durante l'esecuzione del codice Java in essa contenuto.

Ad esempio, nella JSP precedente, se si fornisce una stringa per il parametro eta, al posto di un intero, il metodo Integer.parseInt() scatenerà una NumberFormatException non riuscendo, quindi, a soddisfare la richiesta e causando il seguente errore HTTP 500:

Figura 5. Errore di eccezione non gestita a run time
Errore di eccezione non gestita a run time

Abbiamo visto fin'ora come il Web Application Server si comporti in presenza di errori di compilazione o eccezioni non gestite. In questa parte dell'articolo vediamo come gestire questi errori in modo personalizzato.

Pagine di Errore personalizzate

Per quanto riguarda gli errori a run-time, apriamo una breve parentesi relativamente alla opportunità di visualizzare la pagina di errore generata automaticamente dal server.

Si capisce che, per i non addetti ai lavori, la visualizzazione di una web form contenente informazioni di carattere prettamente tecnico potrebbe risultare poco gradevole e, talvolta, irritante.

Questo è il motivo per cui dovremo fare attenzione ad utilizzare un simile approccio soltanto nelle fasi di sviluppo e collaudo di un'applicazione e, invece, ricorrere ad una pagina più "digeribile" quando porteremo la nostra applicazione in ambiente di produzione.

Per far questo basterà definire una pagina di errore generica, impostando in essa la direttiva isErrorPage a true, e inserire nelle pagine JSP appartenenti alla nostra applicazione l'attributo errorPage, impostandone il valore con la URL della pagina di errore personalizzata (Per specificare delle pagine di errore relative ad un'intera applicazione è possibile avvalersi del tag , da inserire nel file di configurazione web.xml).

Nella nostra semplice pagina JSP (show_user.jsp), ad esempio, basterà inserire all'inizio il seguente tag:

<%@ page errorPage="genericError.jsp" %>

per rindirizzare l'utente alla pagina "genericError.jsp" in caso di errori a run-time. Il codice di una generica pagina di errore potrebbe essere, ad esempio:

Listato 3. Pagina di errore generica

<%@ page isErrorPage="true" import="java.io.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head><title>Errore Applicazione</title></head>

<body>

<h1>Errore</h1>
<p>Si e' verificato un errore imprevisto. Si prega di riprovare piu' tardi.</p>

<p><em><%= exception %></em></p>

<%
  out.println("<!--");
  StringWriter sw = new StringWriter();
  PrintWriter pw = new PrintWriter(sw);
  exception.printStackTrace(pw);
  out.print(sw);
  sw.close();
  pw.close();
  out.println("-->");
%>
</body>
</html>

Inseriamo, adesso, lo stesso input che aveva causato l'ultimo errore HTTP 500 e, questa volta, otterremo:

Figura 6. Eccezione gestita con la pagina di errore
Eccezione gestita con la pagina di errore

Ci sono due cose interessanti da evidenziare nel codice java della pagina di errore:

  • L'oggetto implicito exception (evidenziato in rosso nel codice precedente) viene utilizzato direttamente nell'espressione: <%= exception %>, in quanto automaticamente convertito in stringa
  • Lo scriptlet finale (in grassetto), che consente di raccogliere maggiori informazioni sull'eccezione verificatasi ma che scrive tale contenuto in un commento HTML, in modo che i dettagli tecnici non siano direttamente visibili sulla pagina ma siano consultabili, all'occorrenza, da un tecnico

Infatti, se andiamo a visualizzare il codice sorgente, attraverso il browser, potremo notare le seguenti righe:

Listato 4. Commento generato dalla pagina di errore personalizzata


<!--
java.lang.NumberFormatException: For input string: "Trentanove"
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at org.apache.jsp.show_005fuser_jsp._jspService(show_005fuser_jsp.java:77)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
...
...

-->

Identificazione degli errori attraverso la Servlet generata dal Server

Per prima cosa, riproduciamo l'errore di compilazione iniziale, eliminando un punto e virgola da un'istruzione della nostra pagina JSP e salviamo il codice.

Esiste un ulteriore metodo, come ultima spiaggia, per scovare eventuali errori occorsi durante la compilazione o il processamento di una pagina JSP. Prima, però, è bene rinfrescare la memoria relativamente al flusso che segue una pagina JSP prima di poter essere visualizzata su un browser. Vediamo il grafico seguente:

Figura 7. Flusso di una pagina JSP
Flusso di una pagina JSP

Ogni pagina JSP, alla prima richiesta, viene sempre tradotta e compilata in una servlet. Tutte le susseguenti richieste vengono gestite rifacendosi alla servlet generata e creando dei nuovi thread che processino le singole richieste pervenute.

Dunque, in fase di collaudo, qualora non fossimo riusciti ad identificare un problema attraverso i suggerimenti fin qui descritti, sarà sempre possibile andare ad esaminare direttamente il codice della Servlet associata alla nostra pagina JSP.

In Tomcat, tutte le servlet generate vengono salvate sotto la directory "work/Catalina/localhost".

Figura 8. Directory in Tomcat
Directory in Tomcat

Nel nostro caso, sotto la directory "localhost", troveremo una ulteriore cartella denominata "SimpleJSP", navigando all'interno della quale sarà possibile trovare il codice della Servlet generata, come mostrato nella seguente figura:

Figura 9. Le sottocartelle di "localhost" e l'assenza del file ".class"
Le sottocartelle di

Nel caso mostrato in figura, la nostra Servlet è stata generata ma, per qualche ragione (sappiamo benissimo quale!) Tomcat non è riuscito a produrre il .class. Aprendo il file potremo navigare all'interno del codice e scoprire che c'è una riga (Evidenziata in rosso nel listato 1) che non contiene il punto e virgola finale.

Torniamo, quindi, alla pagina JSP salvata in WebApps/SimpleJSP, correggiamo il codice e rilanciamo l'applicazione. Non ci sorprende, adesso, scoprire che tutto funziona correttamente. Curiosando ancora nella cartella in cui abbiamo trovato il codice sorgente della nostra Servlet, possiamo verificare che il .class è stato adesso regolarmente generato:

Figura 10. Il file ".class" generato senza errori
Il file

Ti consigliamo anche