|
Els JavaBeans, pastilles de
java |
|
|
|
A partir d' pràctica revisarem els
mecanismes per a cridar programes de Java
(Java Beans) des de les nostres pàgines
JSP.
|
|
|
|
Desenvolupament de la pràctica: |
|
|
|
- Repassarem el concepte de Java
Bean.
- Estudiarem el magatzem
de recursos WEB-INF que té qualsevol
aplicació JSP.
- Crearem una pàgina
web que executa Java
Beans.
- Aprofitarem la feina per a crear una segona
pàgina web
"copiant i enganxant" i canviant un
sol paràmetre.
|
|
Repasseu el codi de la pàgina web
que hem creat a la pràctica anterior.
Observareu que, per poc que compliquem els continguts, l'aspecte del
fitxer font és bastant brut: es barreja codi
Java amb codi HTML, i es fa
complicat seguir la seqüència lògica del programa.
Fins un cert punt és un problema inevitable i constitueix el
punt més feble de la programació
JSP. A la literatura informàtica, aquest fenomen rep
el nom de "spaguetti code",
per la il·legibilitat dels fitxers font.
Aquest és un problema que es pot controlar bastant quan és
el mateix programador qui fa el disseny de les pàgines, el
codi Java dels programes i les consultes
SQL a les bases de dades.Però imagineu una empresa que
té dissenyadors web que no saben Java
i programadors de Java que no saben
disseny web. La col·laboració entre els dos sectors
pot fer-se realment complicada si han de compartir el mateixos fitxers
JSP.
Per solucionar aquest problema es poden seguir diferents estratègies.
Totes intenten que les pàgines JSP
tinguin poc codi Java, que els scriptlets
siguin petits o, fins i tot, inexistents i que els programadors
Java puguin fer la seva part de feina
escrivint classes en els seus entorns
de programació habituals.
Nosaltres estudiarem la solució més senzilla: aprendrem
a escriure petits programes -Java Beans-
en el nostre JCreator, els quals
seran cridats després per les pàgines
JSP. D'aquesta forma, a les pàgines
web gairebé tot serà codi
HTML, i podrem crear el suport en
Java amb tots els avantatges d'escriptura i depuració
de l'IDE.
|
|
|
|
Pastilles de Java:
|
|
|
 |
Ja sabem que Java és un llenguatge
concebut per a reutilitzar codi amb facilitat i estalviar costos a
les empreses productores de programes. En aquest context es va crear
el concepte de Bean. Un Java
Bean és un component de software independent
de la plataforma, autocontingut
i reusable que, a més, ha
de poder ser manipulat visualment pels entorns de programació
Java més complets com els
de Borland o de la pròpia
Sun Microsystems. És, doncs,
com una peça de Mecano preparada per a enganxar-la allí
on ens faci falta.
La tecnologia JSP es va dissenyar
per tal de tenir una relació fàcil i natural amb els
Java Beans. Per això es va
crear l'acció <jsp:useBean, que
els crida i manipula amb molt poc cost de codi.
Aquí no estudiarem l'arquitectura
Java Bean, només escriurem algun programa que utilitza
una sintaxi conforme a allò que es demana a un Java
Bean i que, per tant, n'és una expressió mínima.
El nostre objectiu serà fer programes
de Java que s'entenguin fàcilment amb les pàgines
JSP i que retirin de la pròpia pàgina el màxim
de codi Java i així fer-les
més entenedores i fàcils de
mantenir.
Però abans d'escriure una nova pàgina que sigui capaç
de cridar un programa de Java, hem
de descobrir on es desa i com gestiona
codi Java una aplicació JSP.
|
|
|
|
El magatzem de recursos WEB-INF: |
|
|
 |
La nostra aplicació d'exemple viu
en el directori c:/biblioteca.
Aquesta carpeta és la seva arrel
i la podem estendre per tots els directoris que necessitem. Sabem
que si tenim una pàgina JSP
en un subdirectori, per a cridar-la només ens caldrà
escriure el camí al navegador
web (si tenim una pàgina a c:/biblioteca/carnets/imprimir.jsp
la podrem cridar des del navegador web mitjançant http://localhost/carnets/imprimir.jsp).
Aquest principi és cert en tots els casos, menys en un. Hi
ha una carpeta, que el navegador no ens ensenya, que es diu WEB-INF
i que penja immediatament de l'arrel.
El servidor ens prohibeix l'accés
perquè el seu contingut no té a veure amb la navegació
per l'aplicació: és una carpeta
de configuracions i recursos.
Els objectes que es poden trobar
dins WEB-INF són els següents:
- El fitxer
de configuració web.xml.
La seva presència no és imprescindible però
és habitual. Conté la configuració de seguretat
de l'aplicació, sistemes d'autentificació,
mapejat de servlets,
etc.
- La carpeta
/lib, amb les
llibreries de Java,
compilades i freqüentment empaquetades en fitxers .jar,
que utilitza l'aplicació. Imagineu-vos que utilitzeu un programa
de gestió del correu electrònic per a la vostra web,
el codi del qual està empaquetat en un fitxer .jar.
L'haureu de posar a /WEB-INF/lib
per tal que Resin
el pugui trobar.
- La carpeta
/classes. Té
una funció equivalent a la carpeta
/lib (contenir
classes de Java),
però Resin
la tracta de manera diferent: a la carpeta
/lib hi posarem
les llibreries que ja funcionen correctament i que no s'han de revisar
mai. Resin
les carrega a l'iniciar l'aplicació sense més verificacions.
Els continguts presents a la carpeta
/classes, en
canvi, són revisats periòdicament pel servidor
a la recerca de versions noves. Si actualitzem
una classe d'aquesta carpeta, Resin
l'actualitza a l'aplicació. Si ens interessa i configurem
Resin
adequadament, fins i tot podem deixar-hi els fitxers
font *.java
en lloc dels corresponents *.class:
Resin els compil·larà
abans d'utilitzar-los.
Sembla clar, doncs, que el lloc on hem de deixar els fitxers dels
programes que ara escriurem és a la carpeta
c:/biblioteca/WEB-INF/classes. Nosaltres
optarem per deixar els fitxers compil·lats
*.class, no pas els fitxers
font, i així utilitzarem JCreator
per depurar el codi. Si us interessa
que Resin compil·li el codi
-insistim no és la millor opció-, li ho heu de dir en
el fitxer resin.conf. Busqueu aquesta expressió
a c:/resin-2.x.x/conf/resin.conf: <classpath
id='WEB-INF/classes' source='WEB-INF/classes' compile='false'/>
i, a l'opció compile,
poseu-hi 'true'.
|
|
|
|
Una pàgina web que executa Java
Beans: |
|
|
 |
Programar JSP és una manera
particular de programar Java. Malgrat
que els IDEs ja van incorporant poc
a poc eines per a la seva gestió, encara no existeix l'eina
ideal que integri una mica de disseny
de pàgines web, creació
de programes de suport i depuració
del conjunt pàgina JSP-Java Bean.
Darrerament, però, els IDEs
extensibles ja comencen a integrar eines per a la
depuració de servlets i JSP -el projecte
Eclipse disposa, en el moment d'escriure aquestes línies,
de tres plugins per crear
i depurar projectes Resin-.
Nosaltres crearem amb el nostre JCreator
un projecte nou anomenat "Biblioteca",
que ens deixarà el codi compilat
a la carpeta /WEB-INF/classes
corresponent. D'aquesta forma el cicle de creació-depuració-publicació
se simplificarà bastant.
Fem el projecte per als programes de la nostra biblioteca virtual:
- Obrim JCreator.
Fem File | New... | Empty project.
Al projecte
li posem de nom "Biblioteca"
i la localització a c:/biblioteca/WEB-INF/.
Així desem el fitxeret de projecte al magatzem
de recursos de l'aplicació i no
es perd pel disc dur.
- Ara obrim Project
| Project Settings i comprovem que l'"Output
Path" correspon a c:/biblioteca/WEB-INF/classes.
Si no és així, el seleccionem. Si la carpeta no existeix
al nostre disc dur, la creem i després la seleccionem. D'aquesta
forma, quan compilem els programes, JCreator
ens deixarà els fitxers
.class allà
on el servidor Resin
els espera.
- Creem el directori c:/biblioteca/WEB-INF/src,
que serà el lloc on desarem els fitxers
font *.java.
Ja estem a punt per a escriure codi.
Com que una biblioteca emmagatzema llibres, sembla evident que el
primer que hem de fer és crear un objecte
llibre. Ho farem à la Java
Bean:
Amb l'expert
de classes de JCreator
escriviu una nova classe
amb el nom Llibre
i al fitxer Llibre.java,
que residirà a c:/biblioteca/WEB-INF/src.
El codi és aquest, observeu-ne els comentaris per a endevinar
com és l'arquitectura mínima
d'un Java Bean:
|
|
|
|
/**
*
* Llibre conté la informació que descriu un llibre.
* Cadascun dels atributs privats correspon a un camp de la
* taula Llibres a la nostra base de dades.
*
*/
public class Llibre {
/*
* Observeu que tots els atributs d'un Bean són privats.
El Bean és
* una caixa fosca. Només publiquem els atributs que ens
interessen
* els mètodes get() i set()
*/
private int id;
private String autor;
private String titol;
private String editorial;
private String data;
private boolean enprestec;
/*
* Aquí tenim el constructor per defecte. En un Bean el
constructor
* no rep mai paràmetres d'entrada. Així qualsevol
programa que
* utilitzi Beans sap que els podrà instanciar sense paràmetres
*/
public Llibre() {
}
/*
* aquí va tota la llista de mètodes set() (setters)
* Els set ens serveixen per assignar valor als atributs d'un
Bean.
* Els IDES disposen d'eines per a crear grups get() i set()
* automàticament per a tots els atributs privats dels
Beans.
* El nostre JCreator només ho fa en la versió
de pagament. (uns 30€)
*/
public void setId (int id) {
this.id = id;
}
public void setAutor (String autor)
{
this.autor =
autor;
}
public void setTitol (String titol)
{
this.titol =
titol;
}
public void setEditorial (String editorial)
{
this.editorial
= editorial;
}
public void setData (String data)
{
this.data =
data;
}
public void setEnprestec (boolean
enprestec) {
this.enprestec
= enprestec;
}
/*
I aquí tota la llista de mètodes get() (getters).
* els get() ens serveixen per saber el valor dels atributs
*
*/
public int getId () {
return (this.id);
}
public String getAutor () {
return (this.autor);
}
public String getTitol () {
return (this.titol);
}
public String getEditorial () {
return (this.editorial);
}
public String getData () {
return (this.data);
}
public boolean getEnprestec () {
return (this.enprestec);
}
}
|
|
|
|
|
Compilem el codi i, si tot ha sortit bé, comprovem que tenim
un fitxer Llibres.java a c:/biblioteca/WEB-INF/src
i un fitxer Llibres.class a c:/biblioteca/WEB-INF/classes.
Ara tothom que parli Java
ja sap com és un llibre.
La pàgina que farem ens ha de donar la llista de llibres que
hi ha a la nostra base de dades.
Ara farem el nucli del programa,
una aplicació que connecta amb la
base de dades llibres.mdb i que,
quan li ho demanem, ens tornarà una matriu
d'objectes "Llibre" ordenats
alfabèticament. Aquesta matriu
és la llista que sortirà a la nostra pàgina
web.
Escriviu el programa GestioLlibres.java
a c:/biblioteca/WEB-INF/src. Compileu-lo
a l'acabar:
|
|
|
|
import java.sql.*;
public class GestioLlibres {
private Connection connexio;
public GestioLlibres() throws SQLException,
ClassNotFoundException
{
String Urldades
= "jdbc:odbc:biblioteca";
String usuari
= "";
String clau
= "";
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
this.connexio
=
DriverManager.getConnection(Urldades,"","");
}
catch (SQLException e) {
System.out.println(e.getMessage());
}
}
/*
* Amb enprestec indiquem si volem la llista de tots els llibres
* de la biblioteca o només els que estan en préstec
* true - Només els que estan en préstec.
* false - tots els llibres
*/
public Llibre[] getLlibres( boolean
enprestec ) {
//
un vector és una llista que pot rebre qualsevol objecte
// crearem un
vector per a posar-lo la llista de llibres
java.util.Vector
v = new java.util.Vector();
try
{
Statement
pregunta = connexio.createStatement();
ResultSet
resposta = null;
//
Aquí decidim si li demanem a la taula tots els
//
llibres o només els que estan en préstec.
if
(enprestec) {
resposta=pregunta.executeQuery("select
* "+
"from "+
"Llibres
"+
"where
"+
"enprestec
"+
"order
by "+
"titol");
}
else {
resposta=pregunta.executeQuery("select
* "+
"from "+
"Llibres
"+
"order
by "+
"titol");
}
//
Definim un objecte llibre per tal de
//
carregar les dades de la base de dades.
Llibre
unllibre = null;
while
(resposta.next()) {
unllibre
= new Llibre();
unllibre.setId(resposta.getInt("id"));
unllibre.setAutor(
resposta.getString("autor"));
unllibre.setEditorial(
resposta.getString("editorial"));
unllibre.setTitol(
resposta.getString("titol"));
unllibre.setEnprestec(
resposta.getBoolean("enprestec"));
//
Afegim el llibre al vector
v.add(unllibre);
}
pregunta.close();
connexio.close();
}
catch (SQLException e) {
System.out.println(e.getMessage());
}
//
Ara que sabem el nombre de registres que ha de tenir
// ja podem
crear la matriu de llibres
Llibre[] totsllibres
= new Llibre[v.size()];
//
Omplim la matriu de llibres amb el contingut del vector
// d'objectes
Llibre. Atenció: s'ha de fer casting!! per
// dir-li al
compilador quin tipus d'objecte conté el
// vector
for
(int n=0; n<v.size(); n++) {
totsllibres[n]=(Llibre)v.get(n);
}
return totsllibres;
}
}
|
|
|
|
|
Pràcticament, ja està feta tota la feina. A la pàgina
JSP li quedarà molt poc a fer i el seu aspecte serà
molt senzill.
Com s'ho fa la pàgina JSP
per activar els programes Java i
accedir a la seva informació?. A través de l'acció
<jsp:useBean. Observeu i escriviu el
codi de la pàgina web amb
l'inventari de llibres de la nostra biblioteca. Poseu-li de nom llibres.jsp
i deixeu-lo a la carpeta c:/biblioteca:
|
|
|
|
<jsp:useBean id="biblioteca" scope="page"
class="GestioLlibres"/>
<%
Llibre[] elsllibres = biblioteca.getLlibres(false);
%>
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p align="center"><font face="Arial,
Helvetica, sans-serif" size="2"><b>LLISTA
DE LLIBRES DISPONIBLES A LA BIBLIOTECA</b>
</font></p>
<p> </p>
<% if (elsllibres!=null) for (int n=0; n<elsllibres.length;
n++) { %>
<%=elsllibres[n].getAutor()%>;<b><%=elsllibres[n].getTitol()%></b>
<br>
<% } %>
</body>
</html>
|
|
|
|
|
Si no hem fet
errades, a l'engegar Resin i cridar
http://localhost/llibres.jsp
obtindrem la següent llista de llibres: |
|
|
|
 |
|
|
|
Què hem fet?
- La clau rau a l' expressió
que hem posat a dalt de tot de la pàgina
JSP:
<jsp:useBean
id="biblioteca" scope="page" class="GestioLlibres"/> |
Amb aquesta expressió
li hem dit al servidor
que busqui la classe
GestioLlibres
a /WEB-INF/classes,
que en crei una instància,
que li posi de nom "biblioteca"
i que l'abast d'aquest programa
es circumscrigui a la pàgina actual.
Al crear la instància de
GestioLlibres,
la connexió amb la base
de dades s'ha fet automàticament,
perquè s'ha executat el codi que hi ha en el mètode
constructor de la classe GestioLlibres().
- Més avall li demanem al nostre Java
Bean, que, per la pàgina, és
conegut amb el nom de "biblioteca",
que ens retorni la llista de llibres que hi ha a la base
de dades:
<%
Llibre[]
elsllibres = biblioteca.getLlibres(false);
%> |
Declaro una matriu de llibres,
Llibre[], després
la carrego amb el mètode
getLlibres()del
programa. El paràmetre
és false
perquè no vull que em filtri els llibres que són en
préstec.
- Finalment em creo un scriptlet
que em vagi construïnt el llistat a la pàgina
web:
<%
if (elsllibres!=null) for (int n=0; n<elsllibres.length;
n++) { %>
<%=elsllibres[n].getAutor()%>;
<b><%=elsllibres[n].getTitol()%></b><br>
<% } %> |
|
 |
En aquest moment podem aprofitar els nostres esforços i construir
la pàgina JSP que ens llistarà
els llibres que són en préstec.
Ja no hem de codificar res, només hem de copiar el contingut
de la pàgina llibres.jsp
i desar-lo en un altre fitxer que es digui enprestec.jsp
i també posar-lo a c:/biblioteca
L'únic canvi que ens cal fer a la pàgina és
el títol i el paràmetre
que li passem a biblioteca.getLlibres().
En lloc d'escriure
Llibre[]
elsllibres = biblioteca.getLlibres(false) |
escriurem
Llibre[]
elsllibres = biblioteca.getLlibres(true); |
Engeguem Resin i anem a http://localhost/enprestec.jsp.
El resultat ha de ser aquest:

|
|
|
|
A la pràctica següent aprendrem a aprofitar les capacitats
de rebre i enviar informació de les pàgines
web per tal de fer actualitzacions
a la nostra base de dades.
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|