Laboratorio di Sistemi Fattoriale di un numero Jsp [Java

Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
Desideriamo realizzare una applicazione web che ci consenta di calcolare il fattoriale di
un numero. L'esercizio in sé non particolarmente difficile, tuttavia esso ci consentirà di
affrontare il problema da diversi punti di vista.
Modalità 1)
Realizziamo l'applicativo usando gli scriplet:
Pagina index.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h3>Calcolo del fattoriale</h3>
<form name="provaFrm" action="${request.requestURI}">
Dammi un numero intero <input type="text" name="numberTxt" value=""/>
<input type="submit" name="inviaBtn" value="Invia"/>
</form>
<%
// se è stato premuto il pulsante
if (request.getParameter("inviaBtn")!=null) {
// acquisisco il valore stringa della casella testuale
String numberStr = request.getParameter("numberTxt");
try {
// converto la stringa in un numero intero "grande"
long number = Long.parseLong(numberStr);
// cambio il segno se il numero è negativo
if (number < 0)
number = -number;
// trovo il fattoriale col classico algoritmo iterativo
long fatt = 1;
for (int i = 1; i <= number; i++)
fatt = fatt * i;
fattoriale.pdf
Pag. 1/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
// visualizzo il risultato
out.println("<br/><br/>Il fattoriale di "+number+ " è "+fatt);
} catch(NumberFormatException e) {
out.println("<br/><br/>Attenzione! Controlla il valore inserito");
} catch(Exception e) {
out.println("<br/><br/>Errore generico. Messaggio: "+e.getMessage());
}
} // fine if
%>
</body>
</html>
Nel codice precedente, abbiamo anche gestito l'eccezione che si può verificare se
l'utente immette una sequenza qualsiasi di caratteri invece che un numero intero (non
possiamo infatti calcolare il fattoriale di una stringa).
Questo approccio che consiste nell'inserire tutta la logica (la cosiddetta business logic)
nella pagina web index.jsp non è consigliabile in quanto, se vogliamo riutilizzare
l'algoritmo, siamo costretti a fare un copia-incolla del codice.
Modalità 2)
Decidiamo ora di inserire il codice in una classe java molto semplice, che possiamo
riutilizzare tutte le volte che è necessario e in contesti differenti. Ad esempio,
riutilizzando la classe, possiamo progettare un'applicazione GUI (lo sviluppo è lasciato
come esercizio):
fattoriale.pdf
Pag. 2/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
o un'applicazione”console”:
La classe cioè può essere considerata un “componente” riutilizzabile.
/*
* Fattoriale.java
*
*/
package fattPkg;
/**
*
* @author maurizio
*/
public class Fattoriale {
private long number;
/** Creates a new instance of Fattoriale */
public Fattoriale() {
number=1;
}
// “getter”
public long getNumber() {
return number;
}
// “setter”
public void setNumber(long number) {
this.number = number;
}
// metodo che restituisce il fattoriale di number
public long getFattoriale() {
// trovo il fattoriale col classico algoritmo iterativo
long fatt = 1;
fattoriale.pdf
Pag. 3/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
for (int i = 1; i <= number; i++)
fatt = fatt * i;
return fatt;
} // fine metodo getFattoriale
} // fine classe Fattoriale
Questa volta l'algoritmo non si trova più nella pagina web ma è “cablato” nella classe
Fattoriale. Quello che noi dobbiamo fare è utilizzare la classe, istanziando un oggetto
di tipo Fattoriale.
Pagina index2.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h3>Calcolo del fattoriale</h3>
<form name="provaFrm" action="${request.requestURI}">
Dammi un numero intero <input type="text" name="numberTxt" value=""/>
<input type="submit" name="inviaBtn" value="Invia"/>
</form>
<%
// se è stato premuto il pulsante
if (request.getParameter("inviaBtn")!=null) {
// acquisisco il valore stringa della casella testuale
String numberStr = request.getParameter("numberTxt");
try {
// converto in un numero intero "grande"
long number = Long.parseLong(numberStr);
// cambio il segno se l'utente introduce un valore negativo
if (number < 0)
number = -number;
// istanzio l'oggetto fatt che mi servirà per calcolare il fattoriale
fattPkg.Fattoriale fatt = new fattPkg.Fattoriale();
// "settiamo" il valore su cui calcolare il fattoriale
fattoriale.pdf
Pag. 4/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
// (è quello inserito nella casella testuale)
fatt.setNumber(number);
// visualizzo il risultato
out.println("<br/><br/>Il fattoriale di "+number+ " è
"+fatt.getFattoriale());
} catch (NumberFormatException e) {
out.println("<br/><br/>Errore! Ricontrolla i dati inseriti.");
} catch (Exception e) {
out.println("<br/><br/>Errore generico. Messaggio: "+e.getMessage());
}
} // fine if
%>
</body>
</html>
Il vantaggio di questo approccio è quello di svincolare la logica dalla parte di
presentazione affidata alla pagina jsp.
Modalità 3)
Non vi sono sostanziali differenze rispetto all'approccio precedente. Utilizziamo
l'azione standard <jsp:useBean> che equivale a istanziare un oggetto. Impostiamo
successivamente la proprietà (variabile attributo) number al valore inserito nella
casella testuale (dato di input).
Pagina index3.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h3>Calcolo del fattoriale</h3>
<form name="provaFrm" action="${request.requestURI}">
Dammi un numero intero <input type="text" name="numberTxt" value=""/>
<input type="submit" name="inviaBtn" value="Invia"/>
</form>
fattoriale.pdf
Pag. 5/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
<%
// se è stato premuto il pulsante
if (request.getParameter("inviaBtn")!=null) {
// acquisisco il valore stringa della casella testuale
String numberStr = request.getParameter("numberTxt");
try {
// converto la stringa in un numero intero
long number = Long.parseLong(numberStr);
// cambio il segno se l'utente introduce un valore negativo
if (number < 0)
number = -number;
%>
<jsp:useBean id="fatt" class="fattPkg.Fattoriale"/>
<jsp:setProperty name="fatt" property="number" value="<%=number
%>" />
<%
// visualizzo il risultato
out.println("<br/><br/>Il fattoriale di "+number+ " è
"+fatt.getFattoriale());
} catch (NumberFormatException e) {
out.println("<br/><br/>Errore! Ricontrolla i dati inseriti.");
} catch (Exception e) {
out.println("<br/><br/>Errore generico. Messaggio: "+e.getMessage());
}
} // fine if
%>
</body>
</html>
Lo svantaggio di questo approccio è che mescolando HTML e scriplet rendiamo poco
leggibile e mantenibile nel tempo il codice (lo stesso problema affligge anche Php)
Modalità 4)
Questa volta invece di alternare codice java (scriplet) e codice HTML (testo template)
nella pagina web, decidiamo di usare le azioni disponibili nel framework JSTL
(JavaServer Pages Standard Tag Library). Ricordiamoci di inserire nel progetto tali
librerie (tasto destro del mouse su nome del progetto > Properties > Libraries >
Compile > Add Libraries > JSTL 1.1).
Pagina index4.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
fattoriale.pdf
Pag. 6/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h3>Calcolo del fattoriale</h3>
<form name="provaFrm" action="${request.requestURI}">
Dammi un numero intero <input type="text" name="numberTxt" value=""/>
<input type="submit" name="inviaBtn" value="Invia"/>
</form>
<c:if test="${!empty param.inviaBtn}">
<c:set var="number" value="${param.numberTxt}"/>
<c:catch var="e">
<c:if test="${empty number}">
<c:set var="number" value="1"/>
</c:if>
<c:if test="${number<0}">
<c:set var="number" value="${-number}"/>
</c:if>
<jsp:useBean id="fatt" class="fattPkg.Fattoriale"/>
<jsp:setProperty name="fatt" property="number" value="${number}" />
<br/><br/>Il fattoriale di ${number} è <c:out value="${fatt.fattoriale}"/>
</c:catch>
<c:if test="${!empty e}">
<br/><br/>Errore: ricontrolla i dati inseriti
</c:if>
</c:if>
</body>
</html>
fattoriale.pdf
Pag. 7/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
Modalità 5)
In quest'ultimo esempio, introduciamo la nuova classe StringValidation.java. Essa
conterrà una serie di metodi statici che ci consentiranno ad esempio di validare un
numero intero (come nel nostro caso), indirizzi di posta elettronica, codici di
avviamento postale, ssn (social security number) ecc mediante l'utilizzo delle
cosiddette “regular expression” (espressioni regolari).
/*
* StringValidation.java
*/
package fattorialePkg;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author maurizio
*/
public class StringValidation {
/** Creates a new instance of StringValidation */
public StringValidation() {
}
public static boolean isNumeric(String number){
boolean isValid = false;
// denota una sequenza di caratteri
String expression = "[0-9]*";
CharSequence inputStr = number;
// una breve e utile guida sulle espressioni regolari si trova all'indirizzo
// http://www.zparacha.com/java_regex_validation/
Pattern pattern = Pattern.compile(expression);
Matcher matcher = pattern.matcher(inputStr);
if(matcher.matches()){
isValid = true;
}
return isValid;
} // fine metodo isNumeric
// altri metodi di validazione
} // fine classe StringValidation
fattoriale.pdf
Pag. 8/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
Riscriviamo inoltre la classe Fattoriale introducendo alcune modifiche dettate da motivi
di opportunità (sostanzialmente cambiamo il tipo della variabile attributo da long a
String) e scegliamo un valore minimo e un valore massimo per il calcolo del fattoriale.
Per distinguere questa nuova classe dalla precedente, la inseriamo in un altro
package e le assegnamo il nuovo nome FattorialeBean.
/*
* FattorialeBean.java
*
* Created on 31 gennaio 2008, 4.34
*
*
*/
package fattorialePkg;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author maurizio
*/
public class FattorialeBean implements java.io.Serializable {
private String number;
private final static int MIN=0;
private final static int MAX=20;
/** Creates a new instance of FattorialeBean */
public FattorialeBean() {
number="1";
}
// setter di number
public void setNumber(String number) {
this.number=number;
}
// getter di number
public String getNumber() {
return number;
}
// metodo per il calcolo del fattoriale
public long getFattoriale() {
long f=1;
for (int i=1; i<=Long.parseLong(number); i++)
f=f*i;
return f;
}
fattoriale.pdf
Pag. 9/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
// metodo per controllare la validità di un numero intero
public boolean isValidNumber() {
boolean isValid=false;
if (StringValidation.isNumeric(number) && Long.parseLong(number)>=MIN &&
Long.parseLong(number)<=MAX)
isValid=true;
return isValid;
} // fine metodo isValidNumber
} // fine classe FattorialeBean
File index5.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Calcolo del fattoriale di un numero</title>
</head>
<body>
<h3>Calcolo del fattoriale mediante javabean</h3>
<form name="provaFrm" action="${request.requestURI}" method="post">
Introduci un valore intero <input type="text" name="number" value="$
{fatt.number}" />
<input type="submit" name="submit" value="Invia" />
</form>
<c:if test="${!empty param.submit}">
<jsp:useBean id="fatt" class="fattorialePkg.FattorialeBean"/>
<jsp:setProperty name="fatt" property="*"/>
<c:choose>
<c:when test="${fatt.validNumber}">
<br/>Il fattoriale è ${fatt.fattoriale}
</c:when>
<c:otherwise>
<br/>Attenzione! Ricontrolla il valore inserito. Deve essere compreso tra 1
e 20.
</c:otherwise>
</c:choose>
</c:if>
</body>
</html>
fattoriale.pdf
Pag. 10/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
Proviamo a introdurre un valore non previsto dal sistema
fattoriale.pdf
Pag. 11/12
Cozzetto ©
Laboratorio di Sistemi
Fattoriale di un numero
Jsp [Java]
Il valore 21 non è infatti consentito e appare quindi un messaggio di avviso.
Anche l'inserimento di un valore negativo o di una stringa, produce lo stesso effetto.
fattoriale.pdf
Pag. 12/12
Cozzetto ©