Professional Documents
Culture Documents
Walter Montesano
walter.a.montesano@accenture.com
Manual de Java + J2EE
El mundo Java
Al programar en Java no se parte de cero. Cualquier aplicacin que se desarrolle se basa en
un gran nmero de clases preexistentes. Algunas de ellas pueden ser creadas por el propio
usuario, otras pueden ser comerciales, pero siempre hay un nmero muy importante de clases
que forman parte del propio lenguaje (el API o Application Programming Interface de Java).
Java incorpora en el propio lenguaje muchos aspectos que en cualquier otro lenguaje son
extensiones propiedad de empresas de software o fabricantes de computadoras (threads,
ejecucin remota, componentes, seguridad, acceso a bases de datos, etc.). Por eso muchos
expertos opinan que Java es el lenguaje ideal para aprender a programar, porque incorpora
todos estos conceptos de un modo estndar, mucho ms sencillo y claro que con las citadas
extensiones de otros lenguajes. Esto es consecuencia de haber sido diseado ms
recientemente y por un nico equipo.
El principal objetivo del lenguaje Java es llegar a ser el nexo universal que conecte a los
usuarios con la informacin, pudiendo sta residir en la computadora local, en un servidor de
Web, en una base de datos o en cualquier otro lugar.
JDK (Java Development Kit) es el entorno de programacin es suministrado por Sun de forma
gratuita, pudindose encontrar en la direccin web: http://Java.sun.com/j2se/.
Es de consenso que el entorno jdk no es el ms adecuado para el desarrollo de aplicaciones
Java, debido a funcionar nica y exclusivamente mediante comandos de consola, ya que hoy
en da la programacin se suele ayudar de entornos visuales, como JBuilder, JCreator, Eclipse,
BlueJ, etc. Sin embargo, puede ser un entorno bastante til para aprender el lenguaje, ya que
aunque los entornos visuales nos hagan mucho trabajo siempre es necesario ir al cdigo para
modificarlo y obtener el comportamiento deseado, lo cual quiere decir que necesitamos
dominar el lenguaje y es ms fcil llegar a este dominio escribiendo cdigos completos en un
entorno hostil que no nos ayuda, que simplemente remodelando cdigos ya generados por
entornos visuales.
Pgina 2 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Finalmente, JRE (Java Runtime Environment) es un conjunto de programas y bibliotecas que
permiten que un programa Java se ejecute en una computadora. O sea, es el paquete que
instala la mquina virtual en una PC.
El JDK y el JRE se sirven de variables de entorno y de parmetros en las llamadas a los
ejecutables, entre las cuales las ms importantes son:
JAVA_HOME: es la ruta a la raz del JRE. Aunque JBoss busca en esta variable la raz
del JDK.
Caractersticas de Java
La compaa Sun describe el lenguaje Java como simple, orientado a objetos, distribuido,
interpretado, robusto, seguro, de arquitectura neutra, portable, de altas prestaciones,
multitarea y dinmico.
A continuacin, se explicaran algunas de estas caractersticas:
Simple: es un lenguaje sencillo de aprender. Su sintaxis es la de C++ simplificada.
Los creadores de Java partieron de la sintaxis de C++ y trataron de eliminar de este todo lo
que resultase complicado o fuente de errores en este lenguaje.
Orientado a objetos: posiblemente sea el lenguaje ms orientado a objetos de todos
los existentes; en Java todo, a excepcin de los tipos fundamentales de variables (int, char,
long...), es un objeto.
Distribuido: Java est muy orientado al trabajo en red, soportando protocolos como
TCP/IP, UDP, HTTP y FTP. Por otro lado el uso de estos protocolos es bastante sencillo
comparndolo con otros lenguajes que los soportan.
Robusto: el compilador Java detecta muchos errores que otros compiladores solo
detectaran en tiempo de ejecucin o incluso nunca. (ej: if(a=b) then...) el compilador Java no
nos dejara compilar este cdigo.
Seguro: sobre todo en los Applet. Estos son programas diseados para ser ejecutados
en una pgina Web. Java garantiza que ningn Applet puede escribir o leer de nuestro disco o
mandar informacin del usuario que accede a la pgina a travs de la red (como, por ejemplo,
la direccin de correo electrnico). En general no permite realizar cualquier accin que pudiera
daar la mquina o violar la intimidad del que visita la pgina Web.
Portable: en Java no hay aspectos dependientes de la implementacin de los distintos
compiladores, todas las implementaciones de Java siguen los mismos estndares en cuanto a
tamao y almacenamiento de los datos. Esto no ocurre as en C++.
Arquitectura neutral: el cdigo generado por el compilador Java es independiente de la
arquitectura: podra ejecutarse en un entorno UNIX, Mac o Windows. El motivo de esto es que,
el que realmente ejecuta el cdigo generado por el compilador no es el procesador de la
computadora directamente, sino que este se ejecuta mediante una mquina virtual. Esto
permite que los Applets de una Web pueda ejecutarlos cualquier mquina que se conecte a
ella, independientemente de qu sistema operativo emplee (siempre y cuando la computadora
en cuestin tenga instalada una mquina virtual de Java).
Los programas desarrollados en Java presentan diversas ventajas frente a los desarrollados en
otros lenguajes como C/C++. La ejecucin de programas en Java tiene muchas posibilidades:
ejecucin como aplicacin independiente (Stand-alone Application), ejecucin como applet,
ejecucin como servlet, etc. Un applet es una aplicacin especial que se ejecuta dentro de un
navegador o browser (por ejemplo Netscape Navigator o Internet Explorer) al cargar una
pgina HTML desde un servidor Web. El applet se descarga desde el servidor y no requiere
instalacin en la computadora donde se encuentra el navegador. Un servlet es una aplicacin
Pgina 3 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
sin interfaz grfica que se ejecuta en un servidor de Internet. La ejecucin como aplicacin
independiente es anloga a los programas desarrollados con otros lenguajes.
Recolector de basura: El recolector de basura es una caracterstica que permite que
los objetos inicializados, se destruyan automticamente cuando ya no estn referenciados. En
Java no hay que preocuparse por quedarse sin memoria, porque no han sido destruidos los
objetos que ya no estn referenciados. Esto es un problema, por ejemplo en C++, que hay
que destruir manualmente los objetos sin referencias. Java lo hace automticamente.
Palabras reservadas
Existe una serie de palabras reservadas las cuales tienen un significado especial para Java
y por lo tanto no se pueden utilizar como nombres de variables. Dichas palabras son:
abstract
boolean
break
byte
case
catch
char
class
const*
continue
default
do
double
else
extends
final
finally
float
for
goto*
if
implements
import
instanceof
int
interface
long
native
new
null
return
short
package
private
protected
public
static
super
switch
synchronized this
throw
throws
transient
try
void
while
volatile
(*) son palabras reservadas, pero no se utilizan en la actual implementacin del lenguaje
Java.
Variables
Una variable es un nombre que contiene un valor que puede cambiar a lo largo del programa.
De acuerdo con el tipo de informacin que contienen, en Java hay dos tipos principales de
variables:
1. Variables de tipos primitivos. Estn definidas mediante un valor nico que puede ser entero,
de punto flotante, carcter o booleano. Java permite distinta precisin y distintos rangos de
valores para estos tipos de variables (char, byte, short, int, long, float, double, boolean).
2. Variables referencia. Las variables referencia son referencias o nombres de una informacin
ms compleja: arrays u objetos de una determinada clase.
Desde el punto de vista del papel o misin en el programa, las variables pueden ser:
1. Variables miembro de una clase: Se definen en una clase, fuera de cualquier mtodo.
Pueden ser tipos primitivos o referencias.
2. Variables locales: Se definen dentro de un mtodo o, ms en general, dentro de cualquier
bloque entre llaves {}. Se crean en el interior del bloque y se destruyen al finalizar dicho
bloque. Pueden ser tambin tipos primitivos o referencias.
A continuacin se dar una tabla con los distintos tipos de variables y su rango:
TIPO
byte
TAMAO
1 byte
RANGO
Valores numricos de 128 a 127
Pgina 4 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
short
int
2 bytes
4 bytes
long
float
double
char
boolean
8
4
8
2
1
bytes
bytes
bytes
bytes
byte
Como puede apreciar, no existe en Java un tipo de dato primitivo para cadenas de texto. En
su lugar se utiliza una clase, String. Los objetos de esta clase se manipulan por mtodos, por
ejemplo, para comparar cadenas se utiliza equals o equalsIgnoreCase.
if (txtLoc.equalsIgnoreCase(txtLocSel))
Por otro lado, la concatenacin se realiza directamente con el operador +.
cad = txtLoc + ", ARGENTINA";
Si se concatena una cadena con un nmero, ste se convertira a String previamente.
cad = "GBH " + 5
Pgina 5 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
contenido de una variable de jerarqua superior en una de jerarqua inferior) se denomina
cast.
int i = 9,k;
float j = 47.9F;
k = (int)j; //empleo de un cast
Operadores
Los operadores bsicos de Java son + , - , * , / para suma, resta, producto y divisin. El
operador / representa la divisin de enteros si ambos operandos son enteros. Su mdulo
puede obtenerse mediante el operador %.
Adems existen los operadores decremento e incremento: -- y ++ respectivamente. La
operacin que realizan son incrementar y decrementar en una unidad a la variable a la que se
aplican. Su accin es distinta segn se apliquen antes (++a) o despus (a++) de la variable.
Adems de los operadores aritmticos, tenemos los operadores lgicos:
!
==
!=
<
>
<=
>=
&&
&
||
|
Not lgico
Test de igualdad
Test de desigualdad
Menor que
Mayor que
Menor o igual que
Mayor o igual que
And lgico
And lgico (evala todos los trminos siempre)
Or lgico
Or lgico (evala todos los trminos siempre)
Pgina 6 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Operador
+=
-=
*=
/=
%=
Utilizacin
op1 += op2
op1 -= op2
op1 *= op2
op1 /= op2
op1 %= op2
Expresin equivalente
op1 = op1 + op2
op1 = op1 - op2
op1 = op1 * op2
op1 = op1 / op2
op1 = op1 % op2
Operador instanceof
El operador instanceof permite saber si un objeto pertenece o no a una determinada clase. Es
un operador binario cuya forma general es,
objectName instanceof ClassName
Y que devuelve true o false segn el objeto pertenezca o no a la clase. O sea que, por
polimorfismo, tambin devuelve true cuando el objeto es de una clase hija de ClassName, o
bien cuando ClassName es una interfaz y el objeto la implementa.
Operador condicional (?)
Este operador, tomado de C/C++, permite realizar bifurcaciones condicionales sencillas. Su
forma general es la siguiente:
booleanExpression ? res1 : res2
Donde se evala booleanExpression y se devuelve res1 si el resultado es true, y res2 si el
resultado es false. Es el nico operador ternario (tres argumentos) de Java. Como todo
operador que devuelve un valor puede ser utilizado en una expresin.
Estructuras de decisin
Las estructuras de decisin permiten ejecutar una de entre varias acciones, en funcin del
valor de una expresin lgica o relacional. Se tratan de estructuras muy importantes, ya que
son las encargadas de controlar el flujo de ejecucin de un programa.
Existen dos bifurcaciones diferentes: if y switch.
If
Existen tres formas de implementar esta estructura, y son: if, if else e if else if. A
continuacin se explicara cada una de estas implementaciones:
if: esta estructura permite ejecutar un conjunto de sentencias en funcin del valor que
tenga la expresin de comparacin (se ejecuta si la expresin de comparacin tiene valor
true). Tiene la forma siguiente:
if (expresion) {
sentencias;
}
Pgina 7 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Las llaves {} sirven para agrupar en un bloque las sentencias que se han de ejecutar, y no son
necesarias si slo hay una sentencia dentro del if.
if else: anloga a la anterior, de la cual es una ampliacin. Las sentencias incluidas en el
else se ejecutan en el caso de no cumplirse la expresin de comparacin (false):
if (expresion) {
sentencias1;
} else {
sentencias2;
}
if else if: Permite introducir ms de una expresin de comparacin. Si la primera
condicin no se cumple, se compara la segunda y as sucesivamente. En el caso de que no se
cumpla ninguna de las comparaciones se ejecutan las sentencias correspondientes al else.
if (expresion1) {
sentencias1;
} else if (expresion2) {
sentencias2;
} else if (expresion3) {
sentencias3;
} else {
sentencias4;
}
Switch
Se trata de una alternativa a la bifurcacin if else if cuando se compara la misma
expresin con distintos valores. Su forma general es la siguiente:
switch (expresion) {
case valor1:
sentencias1;
break;
case valor2:
sentencias2;
break;
case valor3:
sentencias3;
break;
case valor4:
sentencias4;
break;
case valor5:
sentencias5;
break;
case valor6:
sentencias6;
break;
[default:
sentencias7;]
Pgina 8 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
}
Las caractersticas ms relevantes de switch son las siguientes:
1. Cada sentencia case se corresponde con un nico valor de expresin. No se pueden
establecer rangos o condiciones sino que se debe comparar con valores concretos de tipo
entero (byte, short, int) o con constantes de enumeracin.
2. Los valores no comprendidos en ninguna sentencia case se pueden gestionar en default,
que es opcional.
3. En ausencia de break, cuando se ejecuta una sentencia case se ejecutan tambin todas las
case que van a continuacin, hasta que se llega a un break o hasta que se termina el switch.
Estructuras repetitivas
Se utilizan para realizar un proceso repetidas veces. Se denomina tambin bucle, lazo o loop.
El cdigo incluido entre las llaves {} (opcionales si el proceso repetitivo consta de una sola
lnea), se ejecutar mientras se cumpla unas determinadas condiciones. Hay que prestar
especial atencin a los bucles infinitos, hecho que ocurre cuando la condicin de finalizar el
bucle (expresion) no se llega a cumplir nunca. Se trata de un fallo muy tpico.
Bucle while
Las sentencias se ejecutan mientras expresin sea true.
while (expresion) {
sentencias;
}
Bucle for
La forma general del bucle for es la siguiente:
for (inicializacion; expresion; avance) {
sentencias;
}
Que es equivalente a utilizar while en la siguiente forma:
inicializacion;
while (expresion) {
sentencias;
avance;
}
La sentencia o sentencias de inicializacin se ejecutan al comienzo del for, y la o las
sentencias de avance se ejecutan despus de cada ciclo. La expresin se evala al comienzo
de cada iteracin. El bucle termina cuando la expresin de comparacin (condicin de corte)
toma el valor false. Cualquiera de las tres partes puede estar vaca. La inicializacin y el
incremento pueden tener varias expresiones separadas por comas.
Bucle do while
Pgina 9 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Es similar al bucle while pero con la particularidad de que el control est al final del bucle (lo
que hace que el bucle se ejecute al menos una vez). Una vez ejecutados las sentencias, se
evala la condicin: si resulta true se vuelven a ejecutar las sentencias incluidas en el bucle,
mientras que si la condicin se evala a false finaliza el bucle.
do {
statements
} while (booleanExpression);
Sentencia return
Otra forma de salir de un bucle (y de un mtodo) es utilizar la sentencia return. A diferencia
de continue o break, la sentencia return sale tambin del mtodo o funcin. En el caso de
que la funcin devuelva alguna variable, este valor se deber poner a continuacin del return
(return value;).
Arrays
En Java los arrays son un objeto. Como tales se crean mediante el comando new. La sintaxis
en la definicin de un array es la siguiente:
Tipo_datos[] nombre_array = new Tipo_datos[tamano_array];
Tipo_datos es el tipo de los datos que se almacenarn en el array (int, char, String... o
cualquier objeto). Tamano_array es tamao que le queremos dar a este array. Veamos un
ejemplo:
int[] edades = new int[10];
En este ejemplo hemos definido un array llamado edades, en el que podremos almacenar 10
datos tipo entero. El primer elemento de un array se sita en la posicin 0, exactamente igual
que en C. Si quisisemos realizar un bucle que recorriese los elementos de este array
escribiramos un cdigo del tipo:
for(int i= 0; i< 10; i++){
System.out.println(Elemento + i + edades[i]);
}
Pgina 10 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Veremos ms sobre arreglos ms adelante en este manual (ver Conjuntos de datos).
Clases y herencia
Una clase es la plantilla que usamos para crear los objetos. Todos los objetos pertenecen a
una determinada clase. Un objeto que se crea a partir de una clase se dice que es una
instancia de esa clase. Las distintas clases tienen distintas relaciones de herencia entre si: una
clase puede derivarse de otra, en ese caso la clase derivada o clase hija hereda los mtodos y
Pgina 11 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
variables de la clase de la que se deriva o clase padre. En Java todas las clases tienen como
primer padre una misma clase: la clase Object.
Definicin de una clase
La forma ms general de definicin de una clase en Java es:
[modificador [,modificador*]] class NombreClase [extends
nombreClasePadre] [implements nombreInterface [,nombreInterface*]] {
DeclaracinDeVariables;
DeclaracinDeMtodos;
}
Los campos que van entre corchetes son optativos. NombreClase es el nombre que le
queramos dar a nuestra clase, nombreClasePadre es el nombre de la clase padre, de la cual
hereda los mtodos y variables. Finalmente, tras la palabra implements se ponen todas las
interfaces (separadas por coma) que implementa la clase.
Slo podemos tener una clase public por unidad de compilacin, aunque es posible no tener
ninguna.
Pgina 12 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Fecha unDia = new Fecha(8,12,1999);
Con esta sentencia creamos una variable que se llama unDia con valor 8-12-1999.
Una vez creado un objeto ser posible acceder a todas sus variables y mtodos pblicos, as
por ejemplo en el ejemplo anterior unDia.dia = 8. Si la variable fuese privada (como en el
ejemplo) solo podra acceder a ella el objeto particular al que pertenece esa variable. El nico
capaz de acceder a los atributos privados del objeto es el objeto mismo:
class Fecha{
private int dia;
private int mes
private int ano;
Fecha() {
dia=1;
mes = 1;
ano = 1900;
}
Fecha (int ndia, nmes, nano) {
dia= ndia;
mes = nmes;
ano = nano;
}
}
De este modo no podramos acceder a las variables de la clase fecha, para acceder a ella
tendramos que hacerlo mediante mtodos que nos devolviesen su valor. A esto se le
denomina encapsulamiento. Esta es la forma correcta de programar OOP: no debemos dejar
acceder a las variables de los objetos por otro procedimiento que no sea paso de mensajes
entre mtodos.
A su vez, cuando creamos un objeto de una clase padre, luego podemos apuntar con ese
objeto a un objeto de una clase hija. Por ejemplo:
class Persona {
protected int dni;
}
class Cliente extends Persona {
protected int nroCliente;
}
public class Test {
public static void main (String args []) {
Persona javi;
Cliente hectorCampora;
javi = new Persona();
hectorCampora = new Cliente();
javi = hectorCampora;
}
}
Constructores
Pgina 13 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
El constructor es un mtodo cuyo nombre coincide con el nombre de la clase y que nunca
devuelve ningn tipo de dato, no siendo necesario indicar que el tipo de dato devuelto es void.
Pueden tener distintos accesos (public, protected, private). Este mtodo es llamado
cuando se construye un objeto, es el mtodo responsable de la inicializacin del objeto.
Los constructores se emplean para inicializar los valores de los objetos y realizar las
operaciones que sean necesarias para la generacin de este objeto (crear otros objetos que
puedan estar contenidos dentro de este objeto, abrir un archivo o una conexin de
internet.....).
Como cualquier mtodo, un constructor admite sobrecarga. Cuando creamos un objeto (ya se
ver ms adelante como se hace) podemos invocar al constructor que ms nos convenga.
class animal{
int edad;
String nombre;
public animal(){
}
public animal(int _edad, String _nombre){
edad = _edad;
nombre = _nombre;
}
public void nace(){
System.out.println("Hola mundo");
}
public void get_nombre(){
System.out.println(nombre);
}
public void get_nombre(int i){
System.out.println(nombre +" " +edad);
}
public void get_edad(){
System.out.println(edad);
}
}
Mtodo finalize
En Java no existen los destructores. Para suplir esta ausencia existe un mtodo en la clase
Object que es llamado cuando el recolector de basura ha determinado la inalcanzabilidad de
un objeto y se dispone a "limpiarlo" de la pila. Se trata del mtodo
protected void finalize() throws Throwable;
Si nuestra clase redefine este mtodo, cumplimos con el mismo objetivo que si tuvisemos un
destructor.
Pgina 14 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
this
Es una variable especial de slo lectura que proporciona Java. Contiene una referencia al
objeto en el que se usa dicha variable. A veces es til que un objeto pueda referenciarse a si
mismo:
class Cliente{
public Cliente(String n){
//Llamamos al otro constructor. El empleo de this ha de ser
//siempre en la primera lnea dentro del constructor.
this(n, Cuenta.nuevo_numero());
.....
}
public Cliente (String n, int a){
nombre = n;
numero_cuenta = a;
}
.....
}
Otro posible uso de this, que ya se ha visto en ejemplos anteriores es diferenciar entre
variables locales de un mtodo o constructor y variables del objeto.
public animal(int edad, String nombre){
//this.edad = variable del objeto perro
//edad = variable definida slo dentro del constructor
this.edad =edad;
this.nombre=nombre;
}
super
Del mismo modo que this apunta al objeto actual, tenemos otra variable, super, que apunta
a la clase de la cual se deriva nuestra clase
class Gato {
void hablar(){
System.out.println("Miau");
}
}
class GatoMagico extends Gato {
boolean gente_presente;
void hablar(){
if(gente_presente)
//Invoca al mtodo sobreescrito de la clase padre
super.hablar();
else
System.out.println("Hola");
}
Pgina 15 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
}
Uno de los principales usos de super es, como ya se emple en un ejemplo, llamar al
constructor de la clase padre. En este caso, la llamada a super debe encontrarse en la primer
lnea del constructor.
Modificadores de acceso
Los modificadores son palabras reservadas que asignan, algunos, cierta caracterstica o
particularidad a una clase, a una interfaz, a un atributo o bien a un mtodo. Mientras que
otros, a veces llamados los de visibilidad o de accesibilidad, determinan el mbito del
elemento, desde dnde se va a poder acceder a l, o sea, qu clases pueden utilizarlo.
Los modificadores de accesibilidad son public, protected y private. Si no se utiliza ninguno
de ellos, se asume una visbilidad por defecto segn el caso. Este comportamiento se muestra
en la tabla siguiente en la columna "default" (algunos llaman "package" a este
comportamiento por defecto, dado que la idea siempre es que el elemento sea accesible slo
desde el paquete donde se encuentra).
Los modificadores de caractersticas son static, final, abstract, transient, volatile,
synchronized, native y strictfp.
A continuacin hay una tabla sobre los modificadores ms usados.
Pgina 16 de 62
public
class
protected
N/A
private
N/A
mtodo
visible desde otros paquetes - visible solo dentro del paquete - visible slo dentro de la clase hereda
hereda
no hereda
atributo
visible desde otros paquetes - visible solo dentro del paquete - visible slo dentro de la clase hereda
hereda
no hereda
interface
N/A
N/A
inner class
visible desde otros paquetes - visible solo dentro del paquete - visible slo dentro de la clase hereda
hereda
no hereda
mtodos de
interfaces
atributos de
interfaces
N/A
N/A
N/A
N/A
default
static
final
abstract
N/A
No puede
No puede
tener clases tener clases
hijas - Si es hijas - Si es
final, no
abstract, no
puede ser
puede ser
abstract
final
protected
Mtodo
esttico
Debe estar
en una clase
abstracta, y
No puede ser slo puede
redefinido usar public o
protected. El
mtodo no
tiene cdigo.
protected
Atributo
esttico
Una vez
seteado el
valor, no
puede
modificarse
N/A
No puede
tener
N/A
interfaces
hijas
No puede
No puede
tener clases tener clases
hijas - Si es hijas - Si es
final, no
abstract, no
puede ser
puede ser
abstract
final
N/A
protected
Clase
esttica
public
N/A
N/A
El mtodo no
tiene cdigo
atributo de
clase
Una vez
seteado el
valor, no
puede
modificarse
N/A
Clase
Atributo
Mtodo
Constructor
Bloque de cdigo
public
protected
default
private
final
abstract
static
native
transient
volatile
synchronized
s
no
s
no
s
s
no
no
no
no
no
s
s
s
s
s
no
s
no
s
s
no
s
s
s
s
s
s
s
s
no
no
s
s
s
s
s
no
no
no
no
no
no
no
no
no
s
no
no
no
s
no
no
no
s
Herencia
Cuando en Java indicamos que una clase extends (extiende) otra clase estamos indicando que es
una clase hija de esta y que, por lo tanto, hereda todos sus mtodos y variables. Este es un poderoso
mecanismo para la reusabilidad del cdigo. Al heredar de una clase partimos de su estructura de
variables y mtodos, y luego slo aadimos lo que necesitemos o modificamos lo que no se adapta a
nuestros requerimientos. Veamos un ejemplo:
class animal{
protected int edad;
String nombre;
public animal(){
}
public animal(int _edad, String _nombre){
edad = _edad;
nombre = _nombre;
}
public void nace(){
System.out.println("Hola mundo");
}
public void get_nombre(){
System.out.println(nombre);
Pgina 18 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
}
public void get_nombre(int i){
System.out.println(nombre +" " +edad);
}
public void get_edad(){
System.out.println(edad);
}
}
//La clase perro extiende a animal, heredando sus mtodos y
//variables
public class perro extends animal{
perro(){
edad = 0;
nombre ="Tobi";
}
perro(int edad, String nombre){
//Esta sentencia invoca a un constructor de la clase padre.
super(edad,nombre);
}
//Mtodo esttico que recibe un objeto de tipo perro e
//invoca a su mtodo get_edad()
static void get1(perro dog){
//El mtod get_edad() no est definido en perro, lo ha
//heredado de animal.
dog.get_edad();
}
public static void main (String[] args){
//Creamos un objeto de tipo perro
perro dog = new perro(8,"Bambi");
//Invocamos al mtodo esttico get1 pasndole el objeto
//de tipo perro creado.
perro.get1(dog);
}
}
Cuando se define un mtodo de clase, no podrn existir mtodos de instancia con el mismo nombre
(an cuando devuelvan tipos distintos), ni en la clase que lo defini, ni en las clases que heredan de
ella.
Existen clases que es deseable que existan slo para agrupar un comportamiento comn entre otras
clases; pero esta clase padre no interviene directamente en el negocio, sino a travs de sus clases
hijas. En estos casos, la clase debe declararse abstract, y no podr ser instanciada.
Pgina 19 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Para cumplimentar esto, el compilador se ha diseado utilizando late binding, esto es, la llamada al
mtodo es enlazada con el mtodo puntual en tiempo de ejecucin, en vez de enlazarse en tiempo de
compilacin.
Un aspecto del polimorfismo es lograr que clases hijas modifiquen el comportamiento provisto por el
padre para adaptarlo a sus requerimientos. Este es el concepto de redefinicin (override), escribir un
mtodo en una clase hija con -casi- la misma cabecera que la del mtodo homnimo en la clase
padre. Las nicas diferencias pueden ser:
ampliar la visibilidad
Pgina 20 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
//Cuando ejecutemos este mtodo en vez de ejecutarse
// el cdigo de la clase padre se ejecutar el cdigo de la
// clase hija, ya que sta ha sobreescrito este mtodo.
dog.get_nombre(11);
}
//Sobreescribe al mtodo de la clase padre.
public void get_nombre(int i){
System.out.println(nombre +" " +i);
}
public static void main (String[] args){
perro2 dog = new perro2(8,"hola");
perro2.get1(dog);
}
}
Otro aspecto del polimorfismo sera pretender que el comportamiento de una clase (sus mtodos) se
adapten a distintas peticiones del mismo tipo, o dicho de otra manera, el mismo nombre de mtodo
(peticin) con distina informacin (parmetros).
Java admite lo que se llama sobrecarga (overload) de mtodos: puede haber varios mtodos con el
mismo nombre pero a los cuales se les pasan distintos parmetros. El tipo devuelto no influye: no
puede haber dos mtodos que reciban los mismos parmetros y que devuelvan tipos distintos. Segn
los parmetros que se le pasen se invocar a uno u otro mtodo:
class animal{
int edad;
String nombre;
public void nace(){
System.out.println("Hola mundo");
}
public void get_nombre(){
System.out.println(nombre);
}
public void get_nombre(int i){
System.out.println(nombre +" " +edad);
}
public void get_edad(){
System.out.println(edad);
}
}
Interfaces
En Java no est soportada la herencia mltiple, esto es, no est permitido que una misma clase pueda
heredar las propiedades de varias clases padres. En principio esto pudiera parecer una propiedad
interesante que le dara una mayor potencia al lenguaje de programacin, sin embargo los creadores
de Java decidieron no implementar la herencia mltiple por considerar que esta aade al cdigo una
Pgina 21 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
gran complejidad (lo que hace que muchas veces los programadores que emplean programas que s la
soportan no lleguen a usarla).
Sin embargo para no privar a Java de la potencia de la herencia mltiple sus creadores introdujeron
un nuevo concepto: el de interface. Una interface (o interfaz) es formalmente como una clase, con
tres diferencias: primero, sus mtodos no tienen cuerpo, slo sabecera; segundo, a la hora de
definirla, en vez de emplear la palabra clave class se emplea inteface; y tercero, todos los atributos
sern implcitamente public static final. Vemoslo con un ejemplo:
interface animal{
public int edad = 10; /* es un atributo esttico, an cuando no se
explicite*/
public String nombre = "Bob";
public void nace();
public void get_nombre();
void get_nombre(int i);
}
Cabe preguntarnos cul es el uso de una interface si sus mtodos estn vacos. Bien, cuando una
clase implementa una interface lo que estamos haciendo es una promesa de que esa clase va a
implementar todos los mtodos de la interface en cuestin; de hecho, hasta que no los implemente no
podr ser compilada. De esta forma puede abstraerse un comprtamiento dejando que distintas clases
lo implementen a su manera. Con esto no ahorramos cdigo. Lo que se busca aqu es independencia
de implementacin, algo muy distinto de la reutilizacin de cdigo que se busca con la herencia.
Vemoslo con un ejemplo de una clase que implementa la anterior interface:
interface animal{
public int edad = 10;
public String nombre = "Bob";
public void nace();
public void get_nombre();
void get_nombre(int i);
}
public class perro3 implements animal{
perro3(){
get_nombre();
get_nombre(8);
}
//Comprubese como si cambiamos el nombre del mtodo a nac()
//no compila ya que no henos sobreescrito todos los mtodos
//de la interfaz.
public void nace(){
System.out.println("hola mundo");
}
Pgina 22 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
public void get_nombre(){
System.out.println(nombre );
}
public void get_nombre(int i){
System.out.println(nombre +" " +i);
}
public static void main (String[] args){
perro3 dog = new perro3();
// Compruebese como esta lnea da un error al compilar
// debido a intentar asignar un valor
// a una variable final
// dog.edad = 8;
}
}
Las variables que se definen en una interface llevan todas ellas los modificadores static final, an
cuando no est escrito, y es obligatorio darles un valor dentro del cuerpo de la interface. Adems no
pueden llevar modificadores private ni protected, slo public. Su funcin es la de ser una especie
de constantes para todos los objetos que implementen dicha interface.
Por ltimo decir que aunque una clase slo puede heredar propiedades de otra clase puede
implementar cuantas interfaces se desee, recuperndose as en buena parte la potencia de la herencia
mltiple, como un beneficio extra de las interfaces.
interface animal1{
public int edad = 10;
public String nombre = "Bob";
public void nace();
}
interface animal2{
public void get_nombre();
}
interface animal3{
void get_nombre(int i);
}
public class perro4 implements animal1,animal2,animal3{
perro4(){
get_nombre();
get_nombre(8);
//edad = 10; no podemos cambiar este valor
}
public void nace(){
System.out.println("hola mundo");
}
public void get_nombre(){
System.out.println(nombre );
}
Pgina 23 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
public void get_nombre(int i){
System.out.println(nombre +" " +i);
}
public static void main (String[] args){
perro4 dog = new perro4();
}
}
Clases Internas
Las clases internas (o "embebidas", o "inner") son clases que se encuentran dentro de la definicin de
otra clase. Esto hace suponer que el uso de stas es representar esos casos de inclusin donde la
clase includa tiene cierta complejidad, y tiene un vnculo tan fuerte con la clase envolvente que no es
utilizada nunca por separado, sino siempre como parte de la clase envolvente.
Las posibilidades son:
Tener una clase como un atributo esttico de otra clase. En este caso la clase interna puede
acceder al entorno esttico de la clase (atributos y mtodos estticos).
Tener la clase interna como un atributo. Entonces la clase interna puede acceder a todos los
atributos y mtodos de la clase externa. Para referirse al objeto envolvente actual, puede
utilizarse MiClaseExterna.this.
Encontrar la clase interna definida dentro del cuerpo de un mtodo. La clase interna puede
entonces acceder a toda la informacin del objeto externo, ms una instantnea de los valores
de las variables locales del mtodo.
Tener una clase annima. Estas clases se definen en la llamada a un mtodo (entre los
parmetros).
Las sintaxis para la definicin de una clase annima es la siguiente, dependiendo de si hereda de una
clase o si implementa una interfaz:
new nombreClasePadre ([argumentosDelConstructor]) { cuerpoDeLaClase }
o:
new nomreDeLaInterfaz () { cuerpoDeLaClase }
Pgina 24 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
sino que en la segunda lnea, la variable aux pasa a apuntar a otro objeto, a otra direccin de
memoria, en vez de modificarse la informacin guardada en la primera direccin.
Linea 1:
aux
txt
Linea 2:
aux
txt
txt nuevo
Otra peculiaridad de esta clase es que la instanciacin de nuevos objetos no requiere una llamada
explcita al constructor. En vez de esto:
String aux = new String("algo");
se utiliza esto (por facilidad; lo anterior no producira error alguno):
String aux = "algo";
No es necesario crear una variable para acceder a los mtodos de la clase; los mismos pueden
accederse desde cualquier constante de cadena. El siguiente cdigo es enteramente vlido:
if ("ratoncito".length() > 5) {
Java provee un soporte especial para el operador de concatenacin (+) de cadenas, y para la
conversin de otros objetos a String. La concatenacin se implementa a travs de la clase
StringBuilder o bien de la clase StringBuffer, con el mtodo append. Las conversiones estn
implementadas a travs del mtodo toString de la clase Object.
Los mtodos ms usados son:
char charAt(int index): el mtodo devuelve el caracter que se enuentra en la posicin
"index" (la primera posicin es cero).
"ratoncito".charAt(4) devuelve 'n'
Pgina 25 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
posicin cinco (comenzando desde cero) el caracter 'i' es posterior al caracter 'c'. Tambin
existe el mtodo compareToIgnoreCase que no toma en cuenta diferencias entre maysculas y
minsculas.
boolean equals(Object a): Compara la cadena con un objeto, y devuelve true si el objeto a
no es nulo, y si a representa la misma secuencia de caracteres que la cadena. Tambin existe
el mtodo equalsIgnoreCase que no toma en cuenta las diferencias entre maysculas y
minsculas.
"ratoncito".equals("Ratoncito") devuelve false
int indexOf(char c): Devuelve la posicin donde primero se encontr el caracter 'c' en la
cadena. Si el caracter no se encontr devuelve -1. Adems, se puede especificar desde qu
posicin empezar la bsqueda con el mtodo int indexOf(char c, int startFrom), y se puede
buscar una cadena en vez de un caracter. Tambin existen los mtodos lastIndexOf con las
mismas consideraciones, pero buscando desde atrs hacia adelante en la cadena.
int length(): devuelve el largo de la cadena
"ratoncito".length() devuelve 9
String substring(int beginIdex, int endIndex): devuelve la subcadena que se
encuentra entre la posicin beginIndex y la posicin endIndex-1. El segundo argumento puede
no existir; en ese caso, la subcadena va hasta el final de la cadena original.
"ratoncito".substring(4,6) devuelve "n"
String trim(): devuelve una copia de la cadena, sin los espacios al comienzo y al final de la
misma.
" ratoncito ".trim() devuelve "ratoncito"
Ms informacin en http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html
Clase Math
La clase java.lang.Math contiene mtodos para realizar las operaciones numricas bsicas, tales
como la exponenciacin, la logaritmacin, la raz cuadrada, las funciones trigonomtricas, etctera.
Todas las propiedades y los mtodos de la clase son estticos, por lo que para acceder a ellos no es
necesario instanciar la clase en ningn objeto en particular.
Adems de mtodos, la clase provee las constantes Math.E (base de los logaritmos neperianos),
Math.PI (constante Pi, ambos son double).
Por ejemplo, con Math.pow(double a, double b) obtenemos el resultado de elevar el nmero a a
la potencia b.
Otra funcin importantsima es el mtodo random() para generar nmeros aleatorios. A decir verdad,
para la generacin de nmeros aleatorios la clase Math recurre a otra clase, puntualmente
java.util.Random.
Adems de esta clase (java.lang.Math), se cuenta con un paquete (java.Math) donde se encuentran
definidas unas clases de tipos de datos muy usuales: BigInteger (para modelar un entero grande) y
Pgina 26 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
BigDecimal (para modelar un nmero real exacto -hasta cierta precisin- y no por aproximacin como
float y double). stas suelen ser necesarias para comnicarse con la base de datos.
// Entero aleatorio entre 5 y 27, ambos inclusive
// (la distancia del intervalo es 22)
alea = (int) ((Math.round(Math.random() * 22) + 5));
Ms informacin en http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html
Fechas
Para el manejo de fechas existen varias clases en Java. La principal de ellas es la clase
java.util.Date. Esta clase modela una fecha como la cantidad de milisegundos desde el primero de
Enero de 1970 a las 0:00:00 (a este momento se le denomina "poca"). Para obtener la fecha actual
basta con crear un objeto Date llamando al constructor por defecto.
Las clases java.sql.Date y java.sql.Timestamp fueron creadas para conectar a Java con las bases
de datos, proveyendo tipos de datos de fecha simple y de fecha ms hora respectivamente. Objetos
de estas clases son los que reciben los mtodos setDate y setTimestamp de la clase
PreparedStatement para asignar valores a los parmetros tipo DATE y DATETIME, siempre
respectivamente.
La clase abstracta Calendar apunta a un manejo mucho ms sofisticado de la fecha, con informacin
desde la era hasta el da de semana. La clase hija ms til para el mundo occidental es
GregorianCalendar.
Para el pasaje entre un objeto tipo Date y una cadena de texto se utiliza la clase SimpleDateFormat.
Al construir un objeto de esta clase se especifica un formato, que se utilizar para parsear la cadena
(String -> Date) y para formatear la fecha (Date -> String).
import
import
import
import
java.text.ParseException;
java.text.SimpleDateFormat;
java.util.Date;
java.util.GregorianCalendar;
Pgina 27 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
if (dt != null) System.out.println(sdfSalida.format(dt));
//Obtener informacin ms completa sobre la fecha
// Imprimir la zona horaria
System.out.println(cal.getTimeZone().getDisplayName());
// Imprimir el ao
System.out.println(cal.get(cal.YEAR));
// Imprimir booleano que indica si el ao es bisiesto o no
System.out.println(cal.isLeapYear(cal.get(cal.YEAR)));
// Imprimir las horas de diferencias respecto de Greenwich
System.out.println(cal.get(cal.ZONE_OFFSET)/(1000*60*60));
}
}
La salida por consola de la ejecucin de este programa es:
18/08/1978 00:00:00
Hora de Argentina
2006
false
-3
Conjuntos de Datos
Arreglos (arrays)
Un array es la forma ms bsica de agrupar datos. Todos los elementos del array deben ser del
mismo tipo. Los arreglos se crean con el operador new seguido del tipo y nmero de elementos. Una
vez creado el arreglo con un tamao determinado, ese tamao no puede ser modificado (los arreglos
son conjuntos de tamao fijo).
Se puede acceder al nmero de elementos de un arreglo con la variable miembro implcita length
(por ejemplo, arr.length). Se accede a los elementos de un arreglo con los corchetes [ ] y un ndice
que vara de 0 a length-1. Se pueden crear arreglos de objetos de cualquier tipo. Los elementos de un
arreglo se inicializan al valor por defecto del tipo correspondiente (cero para valores numricos, el
carcter nulo para char, false para boolean, null para referencias a objetos).
Como todos los objetos, los arreglos se pasan como argumentos a los mtodos por referencia. Se
pueden crear arreglos annimos (por ejemplo, crear un nuevo arreglo como argumento actual en la
llamada a un mtodo). La inicializacin de los arreglos se puede realizar de las siguientes maneras:
1. Con valores entre llaves {...} separados por comas.
2. Para arreglos de objetos, con varias llamadas a new dentro de las llaves {...}.
Si se igualan dos referencias a un arreglo no se copia el vector, sino que se tiene un arreglo con dos
nombres, apuntando al mismo y nico objeto. Para crear una referencia a un arreglo son posibles dos
formas:
double[] x; // preferible
double x[];
Luego se deber crear el arreglo en s con el operador new:
x = new double[100];
Pgina 28 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
La creacin de la referencia y la creacin del arreglo mismo se pueden unir en una sola lnea:
double[] x = new double[100];
String dias[] = {"lunes", "martes", "mircoles", "jueves", "viernes", "sbado",
"domingo"};
Un arreglo puede tener tambin dos dimensiones. En ese caso se les denomina matrices. Una matrz
se puede crear directamente en la forma:
int [][] mat = new int[3][4];
O bien se puede crear de modo dinmico dando los siguientes pasos:
1. Crear la referencia indicando con un doble corchete que es una referencia a matriz:
int[][] mat;
2. Crear el arreglo de referencias a las filas:
mat = new int[nfilas][];
3. Reservar memoria para los vectores correspondientes a las filas:
for (int i=0; i<nfilas; i++)
mat[i] = new int[ncols];
A continuacin se presentan algunos ejemplos de creacin de matrices
bidimensionales:
// crear una matriz 3x3
// se inicializan a cero
double mat[][] = new double[3][3];
int [][] b = {{1, 2, 3}, {4, 5, 6}};
int c = new[3][]; // se crea el arr. de referencias a matrices c
[0] = new int[5];
c[1] = new int[4];
c[2] = new int[8];
En el caso de una matriz b, b.length es el nmero de filas y b[0].length es el nmero de columnas
(de la fila 0). Por supuesto, las matrices bidimensionales pueden contener tipos primitivos de cualquier
tipo u objetos de cualquier clase.
Colecciones (Java Collections Framework)
Una coleccin es simplemente un objeto que agrupa mltiples elementos en una sola unidad. Las
colecciones se usan para almacenar, devolver, manipular y comunicar datos en conjunto. Tpicamente
representan datos de un conjunto natural de cosas. Y la Collections Framework es la arquitectura que
unifica la representacin y manipuacin de colecciones. Primeramente, este framework se compone de
una serie de interfaces que definen los tipos de conjuntos que pueden existir. Luego, existen
implementaciones genricas de estas interfaces.
Interfaces
A continuacin se muestran las interfaces que se encuentran en el ncleo de la JCF.
Pgina 29 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Pgina 30 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Clases HashMap y Hashtable
Una tabla hash, o "vector asociativo", es una tabla que mapea "llaves" o "claves" a "valores".
Cualquier objeto no nulo puede ser usado como llave o como valor. La diferencia entre un objeto de la
clase Hashtable y un objeto de la clase HashMap es que el segundo permite valores nulos y la llave
nula. Adems, los mtodos provistos por HashMap son todos sincronizados. Estas clases no garantizan
el orden del mapa; en particular, no se garantiza que el orden permanecer constante en el tiempo.
Recorriendo colecciones
Existen dos formas de recorrer colecciones: con una construccin for-each, y usando Iterator
Construccin for-each
La construccin for-each, introducida en la versin 1.5 del JDK, permite recorrer una coleccin o un
arreglo usando un bucle for. El siguiente cdigo usa la construccin for-each para imprimir cada
elemento de una coleccin en una lnea distinta.
for (Object o : collection)
System.out.println(o);
Ms
informacin
sobre
esta
nueva
forma
de
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/for.html
uso
de
for
en
Clase Iterator
Un Iterator es un objeto que permite recorrer una coleccin y quitar elementos de ella
selectivamente. Se puede obtener un Iterator de una Collection llamando al mtodo iterator().
A continuacin se muestra la definicin de la interfaz Iterator.
public interface Iterator<E> {
boolean hasNext();
E next();
void remove(); //optional
}
El mtodo hasNext() devuelve true si la iteracin tiene ms elementos, y el mtodo next()
devuelve el siguiente elemento en la iteracin. El mtodo remove() quita el ltimo elemento retornado
por next() de la coleccin subyacente. El mtodo remove puede ser llamado una sola vez por cada
llamada a next(), y arrojar una excepcin si esta regla es violada. Este mtodo remove() es la nica
forma segura de modificar una coleccin durante una iteracin.
Pgina 31 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Excepciones
Java incorpora en el propio lenguaje la gestin de errores. El mejor momento para detectar los errores
es durante la compilacin. Sin embargo prcticamente slo los errores de sintaxis son detectados
durante este periodo. El resto de problemas surgen durante la ejecucin de los programas. En el
lenguaje Java, una Exception es un cierto tipo de error o una condicin anormal que se ha producido
durante la ejecucin de un programa.
Algunas excepciones son fatales y provocan que se deba finalizar la ejecucin del programa. En este
caso conviene terminar ordenadamente y dar un mensaje explicando el tipo de error que se ha
producido. Otras, como por ejemplo no encontrar un fichero en el que hay que leer o escribir algo,
pueden ser recuperables. En este caso el programa debe dar al usuario la oportunidad de corregir el
error (indicando una nueva localizacin del fichero no encontrado, por ejemplo).
Un buen programa debe gestionar correctamente todas o la mayor parte de los errores que se pueden
producir. Hay dos estilos de hacer esto:
1. A la antigua usanza: los mtodos devuelven un cdigo de error. Este cdigo se chequea en
el entorno que ha llamado al mtodo con una serie de if else if , gestionando de forma
diferente el resultado correcto o cada uno de los posibles errores. Este sistema resulta muy
complicado cuando hay varios niveles de llamadas a los mtodos.
2. Con soporte en el propio lenguaje: En este caso el propio lenguaje proporciona construcciones
especiales para gestionar los errores o Exceptions. Suele ser lo habitual en lenguajes
modernos, como C++, Visual Basic y Java.
La clase Error est relacionada con errores de compilacin, del sistema o de la JVM. De ordinario
estos errores son irrecuperables y no dependen del programador (excepto los errores de
compilacin...) ni debe preocuparse de capturarlos y tratarlos (aunque el cdigo deber estar libre de
errores para compilarse).
La clase Exception tiene ms inters. Dentro de ella se puede distinguir:
1. RuntimeException: Son excepciones muy frecuentes, de ordinario relacionadas con errores de
programacin. Se pueden llamar excepciones implcitas.
Pgina 32 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
2. Las dems clases derivadas de Exception son excepciones explcitas. Java obliga a tenerlas
en cuenta y chequear si se producen.
El caso de RuntimeException es un poco especial. El propio Java durante la ejecucin de un programa
chequea y lanza automticamente las excepciones que derivan de RuntimeException. El programador
no necesita establecer los bloques try/catch para controlar este tipo de excepciones.
Representan dos casos de errores de programacin:
1. Un error que normalmente no suele ser chequeado por el programador, como por ejemplo
recibir una referencia null en un mtodo.
2. Un error que el programador debera haber chequeado al escribir el cdigo, como sobrepasar
el tamao asignado de un array (genera un IndexOutOfBoundsException automticamente).
En realidad sera posible comprobar estos tipos de errores, pero el cdigo se complicara
excesivamente si se necesitara chequear continuamente todo tipo de errores (que las referencias sean
distintas de null, que todos los argumentos de los mtodos sean correctos, y un largo etctera).
Las clases derivadas de Exception pueden pertenecer a distintos packages de Java. Algunas
pertenecen a java.lang (Throwable, Exception, RuntimeException, ); otras a java.io
(EOFException, FileNotFoundException, ...) o a otros packages. Por heredar de Throwable todos
los tipos de excepciones pueden usar los mtodos siguientes:
Pgina 33 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Las excepciones pueden ser lanzadas directamente por leerFichero() o por alguno de los mtodos
llamados por leerFichero().
Pgina 34 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
...
}
...
} // Fin del metodo1
Puede existir un bloque try sin bloques catch. En este caso se debe incluir un bloque finally para
que se pueda compilar. Esta situacin se presenta cuando dentro del bloque try ningn mtodo puede
lanzar excepciones explcitas pero s implcitas, y deseamos que en ese caso -si surge una de esas
excepciones implcitas-, se haga algo (lo que se encuentra en el bloque finally) antes del abrupto
final del programa, y sin darle ningn tratamiento con bloques catch. Como se puede deducir, no es
una situacin muy comn.
Pgina 35 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
// Cdigo vigilado que puede lanzar una excepcin de tipo A, B o C
} catch (A a1) {
// Se ocupa de la excepcin A
} catch (B b1) {
// Se ocupa de la excepcin B
} finally {
// Sentencias que se ejecutarn en cualquier caso
}
El bloque finally es necesario en los casos en que se necesite recuperar o devolver a su situacin
original algunos elementos. No se trata de liberar la memoria reservada con new ya que de ello se
ocupar automticamente el garbage collector.
Como ejemplo se podra pensar en un bloque try dentro del cual se abre un fichero para lectura y
escritura de datos y se desea cerrar el fichero abierto. El fichero abierto se debe cerrar tanto si
produce una excepcin como si no se produce, ya que dejar un fichero abierto puede provocar
problemas posteriores. Para conseguir esto se deber incluir las sentencias correspondientes a cerrar
el fichero dentro del bloque finally.
Pgina 36 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
JDBC
JDBC (Java DataBase Connectivity) es el framework provisto por Java para conectarse a bases de
datos. La idea es independizar esta comunicacin del motor puntual, brindando una interfaz comn. A
continuacin veremos las caractersticas ms bsicas de la interfaz del desarrollador del API JDBC.
Esto es, la parte del API que un desarrollador Java, dado un manejador para una determinada base de
datos, necesita para interactuar con la base de datos. Esta parte del API permite al desarrollador
realizar tres tareas:
1. Establecer una conexin con una base de datos
2. Enviar una consulta SQL a la base de datos
3. Procesar los resultados de la consulta.
El API JDBC del desarrollador de aplicaciones consta de dos partes, por un lado est el paquete
java.sql, que contiene las clases e interfaces que permiten acceder a la funcionalidad bsica del API
JDBC. Este paquete forma parte de la edicin estndar de la plataforma Java (J2SE), desde la versin
1.1 de sta. Por otro lado estn las clases e interfaces del paquete javax.sql, que forma parte de la
edicin empresarial de plataforma Java (J2EE), las que no sern vistas en este mdulo.
Los manejadores
Los manejadores, tambin llamados drivers, son un conjunto de clases que implementan las clases e
interfaces del API JDBC necesarias para que una aplicacin Java pueda conectarse con una BD.
Cuando los desarrolladores de una BD desean que esta pueda ser accesible mediante JDBC stos
deben implementar un manejador para esa base de datos; la misin del manejador ser traducir
comandos estndar del API JDBC al protocolo nativo de esa base de datos.
Cada base de datos emplea un protocolo diferente de comunicacin, protocolos que normalmente son
propietarios. El uso de un manejador, una capa intermedia entre el cdigo del desarrollador y la base
de datos, permite independizar el cdigo Java que accede a la BD del sistema de BD concreto a la que
estamos accediendo, ya que en nuestro cdigo Java emplearemos comandos estndar, y estos
comandos sern traducidos por el manejador a comandos propietarios de cada sistema de BD
concreto. Si queremos cambiar el sistema de BD que empleamos lo nico que deberemos hacer es
reemplazar el antiguo manejador por el nuevo, y seremos capaces de conectarnos la nueva BD.
Tipos de manejadores
Hay 4 tipos de manejadores JDBC, que difieren en si usan o no tecnologa Java pura, en su
rendimiento y en la flexibilidad para cambiar de base de datos. Veamos cuales son:
Puente JDBC-ODBC (tipo1)
ODBC es un API estndar semejante a JDBC, que permite que lenguajes como C++ accedan de un
modo estndar a distintos sistemas de BD. Un manejador tipo puente JDBC-ODBC delega todo el
trabajo sobre un manejador ODBC, que es quien realmente se comunica con la BD. El puente JDBCODBC permite la conexin desde Java a bases de datos que no proveen manejadores JDBC. Fue muy
til cuando se cre el API JDBC, ya que muchas BD no disponan de manejadores JDBC, pero s de
manejadores ODBC. Empleando el puente JDBC-ODBC poda accederse a estas bases de datos
empleando el API JDBC. Este tipo de manejador tiene dos desventajas: por un lado depende de cdigo
nativo, ya que el manejador ODBC no ha sido desarrollado en Java. Esto compromete la portabilidad
de nuestro desarrollo. Por otro lado al emplear este tipo de manejador nuestra aplicacin llama al
Pgina 37 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
gestor de manejadores JDBC, quien a su vez llama al manejador JDBC (puente JDBC-ODBC), quien
llama al manejador ODBC, que es el que finalmente llama a la base de datos. Hay muchos puntos
donde potencialmente puede producirse un fallo, lo cual hace que estos manejadores muchas veces
sean bastante inestables.
El puente forma parte del jdk de SUN, est en el paquete sun.jdbc.odbc. Inicialmente este tipo de
manejador fue bastante til por aliviar la carencia de manejadores JDBC. Hoy en da es el menos
recomendado por limitar la portabilidad de la aplicacin, al requerir cdigo nativo, y por emplear
tantas capas para la comunicacin con la base de datos, lo que a veces hace que se incremente la
inestabilidad de estos manejadores.
Manejador nativo (tipo2)
Se basa en una biblioteca escrita en cdigo nativo para acceder a la base de datos. El manejador
traduce las llamadas JDBC a llamadas al cdigo de la librera nativa, siendo el cdigo nativo el que se
comunica con las bases de datos. La librera nativa es proporcionada por los desarrolladores de la BD.
Estos manejadores son ms eficientes y tienen menos puntos de fallo que el puente JDBC-ODBC ya
que hay menos capas entre el cdigo de la aplicacin y la base de datos. Sin embargo siguen teniendo
el problema de prdida de portabilidad por emplear cdigo nativo.
Pgina 38 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Pgina 39 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Pgina 40 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Clase DriverManager
Como su nombre indica esta clase es la gestora de los diversos drivers (manejadores) que haya en
nuestra aplicacin. Es posible que sea necesario en una misma aplicacin tener varios manejadores
para una misma base de datos, acceder a varias bases de datos que emplean distintos manejadores, o
bien ambas situaciones a la vez. De ah el inters de contar con este gestor de manejadores.
Los mtodos que ms nos interesan de esta clase son
static Connection getConnection(String url) y
static Connection getConnection(String url, String user, String password)
Estos mtodos intentan establecer conexin con la base de datos que le indiquemos en el campo url
empleando para ellos todos los manejadores que hemos registrado. La diferencia entre un mtodo y el
otro, obviamente, es que en uno slo se especifica la base de datos a la que nos queremos conectar,
mientras que en el otro se indica tambin el nombre de usuario de la base de datos y su password.
Ms adelante explicaremos que es el objeto Connection que devuelven estos mtodos.
Lo que hace la clase DriverManager para intentar establecer conexin con la base de datos es invocar
al mtodo connect de la interface Driver, interface que como veremos deben implementar todos los
manejadores. Esta operacin se realizar con todos los manejadores que estn registrados; si el
manejador devuelve null significa que no se ha podido conectar con la base de datos; entonces el
gestor intenta de nuevo conectarse con otro manejador. Si consigue conectarse con un manejador no
sigue intentndolo con el resto de los manejadores registrados, y si no consigue establecer la
conexin con ningn manejador lanza una excepcin tipo SQLException.
Pgina 41 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Pgina 42 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
As por ejemplo la URL: jdbc:bdnet://kwcserver:4040/usuarios Empleara el protocolo jdbc y un
manejador de tipo JDBC-Net para conectarse a la hipottica base de datos usuarios a travs del
puerto 4040 de la mquina kwcserver.
Registro de un manejador
Registrar un manejador no es ms que cargar en memoria una clase que implementa el interfaz
Driver, clase proporcionada por los desarrolladores de la base de datos. Existen tres formas de
registrar un driver:
1. Empleando el cargador de clases. Para ello empleamos, al igual que para cargar cualquier otra
clase, el mtodo forName(String clase) de la clase Class.
Class.forName("com.mysql.Driver");
2. Instanciando la clase que implementa el interfaz Driver. De este modo tendremos una
referencia al driver, pudiendo establecer la conexin directamente con l sin necesidad de
emplear la clase DriverManager. La sintaxis es la misma que para instanciar cualquier otra
clase:
Driver driverPraMySQL = new com.mysql.jdbc.Driver();
3. Definir la propiedad jdbc.drivers. Podemos hacerlo de dos modos diferentes:
a. Definiendo la propiedad jdbc.drivers en nuestra mquina virtual. La sintaxis es:
jdbc.drivers=nombreManejador1: nombreManejador2:
jdbc.drivers=gjt.mm.mysql.Driver:oracle.jdbc.driver.OracleDriver;
b. Emplear la opcin D al invocar a la mquina virtual. Para ello debemos arrancar
nuestra aplicacin con el comando
java -Djdbc.drivers=nombreManejador1: nombreManejador2:
java -Djdbc.drivers=gjt.mm.mysql.Driver:oracle.jdbc.driver.OracleDriver;
Interfaz Driver
Aunque es vital para establecer la conexin con la base de datos en la prctica el desarrollador de
aplicaciones puede olvidarse de esta interfaz. Es responsabilidad del desarrollador del manejador
proveer una clase que implemente esta interfaz, y ser responsabilidad del DriverManager llamar al
mtodo connect de los drivers registrados para intentar establecer la conexin con la base de datos.
No obstante es, posible crear un objeto tipo Driver -instanciando la clase desarrollada por el
desarrollador del manejador- e invocar directamente a su mtodo connect, obteniendo una conexin
con la base de datos sin necesidad de emplear la clase DriverManager. De este modo tenemos ms
control sobre el driver que estamos empleando en la conexin, cuando hemos registrado ms de un
driver, ya que no nos arriesgamos a que se establezca conexin con la BD con un driver distinto al que
nosotros deseamos usar.
Interfaz Connection
Representa una conexin con la base de datos. Permite crear objetos que representan consultas que
se ejecutarn en la base de datos, y permite acceder a informacin sobre la base de datos y las
posibilidades del manejador JDBC.
En la tabla recogemos los principales mtodos de la interfaz Connection.
void close()
void commit()
Statement
createStatement()
Pgina 43 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
boolean getAutoCommit()
DatabaseMetaData getMetaData()
Interfaz Statement
Esta interfaz permite enviar instrucciones SQL a la base de datos. Podemos obtener un objeto que
implemente esta interfaz a partir del mtodo Statement createStatement() de la interfaz
Connection. Para enviar una consulta tipo SELECT se emplea el mtodo execteQuery(String sql).
Este mtodo devuelve un objeto tipo Resultset. Para enviar una instruccin tipo DELETE, UPDATE,
INSERT o una instruccin DDL (Data Definition Language) se emplea executeUpdate(String sql).
Mediante el mtodo execute(String sql) podemos ejecutar cualquiera de los comandos anteriores.
El mtodo execute devuelve un booleano indicando si hay ResultSet o no. En caso de haberlo, se lo
puede recuperar con el mtodo getResultSet(). El mtodo executeUpdate devuelve un entero
indicando la cantidad de registros afectados. Y el mtodo executeQuery devuelve un ResultSet.
Interfaz PreparedStatement
Representa una instruccin SQL preparada, esto es, una instruccin SQL precompilada cuya ejecucin
es mucho ms eficiente que ejecutar repetidas veces una misma instruccin SQL. Cuando vayamos a
ejecutar varias veces las mismas instrucciones debemos emplear esta interfaz.
Podemos obtener un objeto que implemente esta interfaz a partir del mtodo PreparedStatement
createPreparedStatement(String sql) de la interfaz Connection. La interfaz PreparedStatement
extiende a Statement aadiendo una serie de mtodos setXXX(int indice, XXX valor) que
permiten, para cada ejecucin de la instruccin, asignar un valor a los parmetros de la instruccin
SQL precompilada (los parmetros comienzan de 1). El primer valor, siempre un entero, es el ndice
del parmetro al cual le vamos a asignar un valor, empezando a contar en 1, y valor es el valor que
le asignamos a ese parmetro.
Interfaz CallableStatement
Permite ejecutar procedimientos almacenados. Extiende a la interfaz PreparedSatatement. Podemos
obtener un objeto que implemente esta interfaz a partir del mtodo CallableStatement
prepareCall(String sql) de la interfaz Connection.
Los parmetros de entrada (o de entrada-salida) del procedimiento almacenado deben ser setados con
los mtodos set heredados de PreparedStatement. Los parmetros de salida (o los de entradasalida) deben ser registrados (con su correspondiente tipo) antes de la ejecucin mediante el mtodo
registerOutParameter().
Pgina 44 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Luego de la ejecucin, los parmetros de salida se pueden obtener a travs de mtodos get. Tambin
pueden obtenerse uno o ms objetos ResultSet.
Interfaz ResultSet
Esta interfaz representa un conjunto de datos que son el resultado de una consulta SQL. La clase
posee una serie de mtodos XXX getXXX(int columna) y XXX getXXX(String columna) que
permiten acceder a los resultados de la consulta (para la sintaxis concreta de estos mtodos acudir al
javadoc de la interfaz ResultSet). La diferencia entre el primer tipo y el segundo es que en el primero
usamos ordinales de columnas (empezando desde 1) mientras que en el segundo usamos nombres de
columnas. Para acceder a los distintos registros empleamos un cursor, que inicialmente apunta justo
antes de la primera fila. Para desplazar el cursor empleamos el mtodo next().
Pgina 45 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Pgina 46 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
La correspondencia entre tipos de datos Java y tipos de datos SQL se muestra en la siguiente tabla:
Tipo Java
boolean
byte
short
int
long
float
double
java.math.BigDecimal
String
byte[]
java.sql.Date
java.sql.Time
java.sql.Timestamp
Tipo SQL
BIT
TINYINT
SMALLINT
INTEGER
BIGINT
REAL
DOUBLE
NUMERIC
VARCHAR o LONGVARCHAR
VARBINARY o LONGVARBINARY
DATE
TIME
TIMESTAMP
Debemos tener en cuenta siempre que cada objeto Resultset est ligado al objeto Statement que lo
gener, y al objeto Connection de donde se obtuvo ese Statement. Por esto, si tenemos un objeto
Resultset y ejecutamos una sentencia tipo SELECT con el Statement que lo haba generado, los
resultados de la anterior consulta se perdern, al igual que si la conexin a la base de datos se cierra.
// Mientras queden resultados por procesar.
// Recuerde que next() desplaza el cursor del Resulset una
// posicin hacia delante cada vez que se invoca.
while (resultset.next()) {
// Accedemos a los resgistros resultado mediante los mtodos
// getXXXX Indicando el nombre de la columna
System.out.println(resultset.getString("NOMBRE")+
", gracias por ser un usuario tan activo !");
}
Liberar los recursos de la conexin
Una vez que hayamos terminado las operaciones que queramos realizar en la base de datos debemos
liberar todos los recursos que estaba consumiendo la conexin. Aunque estos recursos son
automticamente liberados por el GarbageCollector cuando sus correspondientes objetos son
eliminados, es buena practica liberarlos manualmente, para que esta liberacin se produzca en cuanto
dejan de ser tiles.
Los recursos que debemos liberar son el Resultset, el Statement y la propia conexin. Para liberarlos
debemos invocar al mtodo close() de sus correspondieres objetos. Invocar al mtodo close() de
Statement automticamente libera los recursos de su ResultSet.
// No nos olvidemos de liberar todos los recursos que hemos empleado una
// vez que no necesitemos la conexin: debemos liberar tanto los recursos
// consumidos por el Resulset, por los Statement empleados y las propias
// Conexiones
try {
resultset.close();
statement.close();
conexion.close();
}catch(SQLException e){}
Pgina 47 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Metainformacin
Pgina 48 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
El API JDBC nos permite acceder a metainformacin sobre la base de datos y sobre el ResultSet
generado por una consulta, es decir, a informacin a cerca de las caractersticas (no del contenido) de
la base de datos y del Resultset, informacin como el nombre de la base de datos, la versin, el
nmero y nombre de las columnas del Resultset, etc.
La metainformacin de la base de datos est representada por un objeto que implementa la interfaz
java.sql.DatabaseMetaData, objeto al cual nos da acceso el mtodo getMetaData() de la interface
Connection. En DatabaseMetaData hay, por ejemplo mtodos como getDriverName(), que nos
devuelve el nombre del driver que estamos empleando, getDriverVersion(), que nos devuelve la
versin del driver, getDatabaseProductName(), el nombre de la base de datos, getURL(), la URL de
esta base de datos, etc.
La metainformacin del ResultSet est representada por un objeto que implementa la interfaz
ResultSetMetaData, accesible mediante el mtodo getMataData() de la interfaz ResultSet. En esta
interfaz tenemos mtodos para, por ejemplo, averiguar el nmero de columnas del ResultSet
getColumnCount(), el nombre de cada columna, getColumnName(int columna), saber si podemos
escribir en una columna, isWritable(int columna), clase Java correspondiente a una columna,
getColumnClassName(int columna), etc.
En este cdigo se accede a la metainformacin del ResultSet para averiguar el nmero y nombre de
las columnas, y se imprime una tabla en la consola con el resultado.
public static void imprimeConsulta(ResultSet resultSet) {
try {
//Obtenemos la Metainformacin de ResulSet
ResultSetMetaData resultSetMetaData =
resultSet.getMetaData();
//A partir de la metainformacin obtenemos el nmero de
//columnas
int numeroDeColumnas =
resultSetMetaData.getColumnCount();
//Para todas las columnas
for (int i = 1; i <= numeroDeColumnas; i++) {
//Averguamos cual es el nombre de cada columna
String nombreDeLaColumna =
resultSetMetaData.getColumnName(i);
stringBuffer.append(nombreDeLaColumna + "\t");
}
//Ahora recorremos el resulset igual que en el primer ejemplo
while (resultSet.next()) {
//Accedemos a todas las columnas del registro
for (int i = 1; i <= numeroDeColumnas; i++) {
//Acedemos a todas como String, aunque empleando la
//metainformacin sera posible averiguar que tipo de dato es
stringBuffer.append(resultSet.getString(i) + "\t");
}
}
System.out.println(stringBuffer.toString());
}
Transacciones
Una transaccin es un conjunto de operaciones que deben de realizarse de un modo atmico sobre la
base de datos, esto es, o bien se realizan todas ellas correctamente, o bien no se realiza ninguna. Las
transacciones son importantes para mantener la consistencia de la informacin en la base de datos.
Pgina 49 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Imaginemos que tenemos un registro en la tabla usuario, la clave primaria de este registro es
referenciada por un registro en una tabla llamada pedidos. Borrar a ese usuario implica borrar los
pedidos que haya hecho ese usuario; en este caso podemos hacerlo con dos instrucciones DELETE,
una sobre el registro del usuario y la otra sobre el pedido. Si la primera instruccin tiene xito, y la
segunda no, en la base de datos tendremos un pedido que referencia a un usuario que no existe. Para
evitar este problema podemos agrupar las dos operaciones de borrado en una misma transaccin; de
ese modo o eliminamos ambos registros o no eliminados ninguno. En cualquier caso la informacin de
la base de datos ser consistente.
Para emplear transacciones con el API JDBC debemos invocar el mtodo setAutocommit(false) de la
interfaz Connection. Por defecto la interfaz Connection ejecuta un commit, es decir, una confirmacin
de los cambios realizados en la base de datos, cada vez que ejecutamos una sentencia. Este mtodo
nos permite activar y desactivar este comportamiento.
A continuacin ejecutamos las operaciones que deseemos agrupar en una nica transaccin, y
finalmente, si queremos confirmar los cambios, invocamos el mtodo commit(), del interfaz
Connection. En ese momento los cambios realizados se harn permanentes en la base de datos y se
liberar cualquier tipo de bloqueo que haya realizado esta conexin.
Si queremos cancelar los cambios invocamos al mtodo rollback(), tambin de la interfaz
Connection. Este mtodo deshace todos los cambios hechos en la base de datos desde el ltimo
commit o rollback y libera cualquier tipo de bloqueo que haya realizado esta conexin. Cuando se
gestionan las excepciones del cdigo transaccional, siempre se suele poner un rollback en el catch, de
ese modo si hay un error en la ejecucin de alguna de las operaciones de la transaccin deshacemos
los cambios de las que se ejecutaron con xito.
De todas formas, cuando se desea trabajar con transacciones, lo primero a realizar es desactivar el
modo auto-commit con el mtodo setAutocommit(false), pues las conexiones son creadas por
defecto en modo auto-commit.
Control de la concurrencia
Al emplear transacciones para acceder a la base de datos pueden surgir una serie de problemas si hay
varias conexiones abiertas al mismo tiempo contra la base de datos (la base se est accediendo de
modo concurrente). Es importante conocer y entender cuales son esos problemas, as como conocer
que niveles de aislamiento transaccional nos proporciona el API JDBC para evitarlos.
Los problemas que pueden surgir son:
1. Lecturas sucias: una fila de la base de datos que ha sido modificada por una transaccin y
antes de que esta transaccin ejecute un commit (si es que finalmente llega a ejecutarse) esa
fila es leda por otra transaccin.
1. Lecturas no repetibles: una transaccin lee una fila, otra transaccin modifica esta fila y la
primera transaccin vuelve a leer la fila, pero esta vez obtiene un resultado diferente de la
primera lectura.
2. Lecturas fantasmas: una transaccin selecciona todos los registros que satisfacen una
determinada condicin, otra transaccin inserta un nuevo registro que satisface esa condicin.
La primera transaccin vuelve a seleccionar todos los registros que satisfaces la misma
condicin, pero esta vez obtiene un registro adicional, el que insert la segunda transaccin.
Control del nivel de aislamiento transaccional
El API JDBC nos permite controlar el nivel de aislamiento transaccional, esto es, cuales de los tres
problemas recogidos en el apartado anterior vamos a tolerar en nuestra conexin y cuales no. Para
ello empleamos el mtodo setTransactionIsolation(int nivel) de la interfaz Connection. El
entero que se le pasa es una variable esttica y final definida dentro de la interfaz Connection. Los
posibles valores son:
Pgina 50 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
1. Connection.TRANSACTION_NONE: Indica que la conexin no soporta transacciones. Podemos
obtener el nivel de aislamiento de una conexin mediante el mtodo getTransactionIsolation(),
si su valor es ste, significa que la conexin no soporta transacciones.
2. Connection.TRANSACTION_READ_UNCOMMITED: Permite que sucedan lecturas sucias, fantasmas
y no repetibles. Si una transaccin finalmente ejecuta un rollback() otras transacciones
pueden haber ledo informacin incorrecta.
3. Connection.TRANSACTION_READ_COMMITED: Permite que sucedan lecturas fantasmas y no
repetibles, pero no lecturas sucias.
4. Connection.TRANSACTION_REPETABLE_READ: Slo permite que sucedan lecturas fantasmas,
las lecturas sucias y no repetibles no sucedern.
5. Connection.TRANSACTION_SERIALIZABLE: Evita lecturas fantasmas, sucias y no repetibles.
Podra parecer que lo ideal es emplear siempre el mximo aislamiento transaccional, sin embargo esto
disminuye notablemente el rendimiento de la base de datos. En general el rendimiento de los accesos
a la base de datos es inversamente proporcional al nivel de asilamiento transaccional que empleemos,
por lo que debemos estudiar detenidamente que nivel trasnacional nos podemos permitir en nuestra
aplicacin.
Pgina 51 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
J2EE
Introduccin al modelo (1.4)
J2EE es un modelo para el desarrollo de aplicaciones Java. Fue introducido por Sun en el ao 1998
como un conjunto englobador de las tecnologas de servidor Java ya existentes para la poca. O sea
que Servlets, JSPs y EJBs existan desde antes de la presentacin del modelo.
El modelo se basa en la arquitectura cliente-servidor.
Esto de "modelo" se refiere a que se est proponiendo un patrn para estructurar una aplicacin. En
ese sentido es un norte, una primera gua cuando se est diseando la arquitectura de una solucin
software. A partir de ah, cada aplicacin tiene sus particularidades, lo que hace que sean muy pocas
las que implementarn todo el modelo completo y sin alteraraciones. En el choque entre un modelo
puramente conceptual y la realidad de cada aplicacin, se sabe que no sera conveniente aplicar
exactamente el mismo patrn a todas las aplicaciones posibles. Entonces, el modelo est pensado
teniendo en cuenta esta posterior adaptabilidad al caso. Como consecuencia, en ciertos puntos se
limita a proponer la solucin ms avanzada, y en otros recurre a la tecnologa ms usada al momento
de concebirse.
Por ejemplo, podra haberse elegido seguir el modelo J2EE. Pero por el tamao de la aplicacin -dicho
de otra forma, el presupuesto-, y por la mantenibilidad requerida -para no excederse del presupuesto
se acept una mantenibilidad no ptima-, el arquitecto podra proponer implementar una aplicacin
web con Servlets y JSPs. En este caso la capa de negocio quedara a cargo de los mismos Servlets.
Cada capa est pensada para que pueda ejecutarse en computadoras diferentes. Aunque el espectro
es amplio: podramos tener ms de una capa en una misma computadora (imaginemos un servidor
web andando en una mquina y desde esa misma mquina acceder al sitio como un cliente ms); o
bien podramos tener una misma capa alojada en ms de una computadora (por ejemplo, cuando los
datos residen en ms de un servidor de bases de datos, replicndose mutuamente).
Pgina 52 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Para llevar a cabo el trabajo tendremos "componentes", que no son otra cosa que programas (objetos,
dentro del mundo Java). Estos componentes se ejecutarn en un "contenedor" apropiado. El
contenedor brinda funcionalidad al componente que aloja, al mismo tiempo que le impone
restricciones. Por ejemplo, podra encargarse de la persistencia de un bean de entidad (la persistencia
siendo el guardar y recuperar informacin del bean en una base de datos), pero ese bean de entidad
debe ajustarse a cierta versin de interfaz para que pueda ejecutarse en el contenedor.
Veamos qu componentes y contenedores se encuentran en cada capa:
Capa
Cliente
Contenedor
Client container
Presentacin
Web container
Lgica de negocio
Datos
EJB container
Contenedor includo
HTML container
Applet container
Servlet container
JSP container
Componente
HTML, JS
Applets
Servlets
JSPs
EJBs
Despliegue
El despliegue o deployment (del verbo "deploy", desplegar) es la "instalacin" de un mdulo (un
conjunto de componentes de una misma capa) en un contenedor. La aplicacin, tras haber sido
desarrollada, se comprime en un archivo con una estructura y una extensin dependientes del tipo de
mdulo de que se trate. Este archivo comprimido cuenta con un "descriptor de despliegue" o
"deployment descriptor" que indica ciertas caractersticas de la aplicacin, como los nombres JNDI
requeridos, la configuracin de seguridad, de persistencia, etc.
El mdulo web se empaqueta en un archivo .war que contiene sus componentes web (JSPs y Servlets,
ms archivos de recursos como grficos).
El mdulo EJB se empaqueta en un archivo .jar que contiene los EJBs.
Y ambos archivos (.war y .jar) se empaquetan en archivos .ear, que corresponden al mdulo de
aplicaciones de empresas. Un archivo .ear puede contener de 0 a n archivos .war, y de 0 a n archivos
.jar.
Mdulo
Aplicacin de empresa
Aplicacin Web
Aplicacin EJB
Descriptor de despliegue
application.xml
web.xml
ejb-jar.xml
Pgina 53 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Es comn que se utilice, adems del descriptor de despliegue estndar, un descriptor de despliegue
particularizado para el contenedor. Una vez ms, lo que en un principio se concibi para ser estndar,
termina "personalizndose" y rompiendo el estndar.
Lo que s es estndar es la estructura de carpetas que tiene un archivo comprimido. Pero si al
exportarse la estructura es la misma, no significa que mientras se desarrollaba los archivos hayan
estado distribuidos en carpetas idnticas. De hecho, la estructura mientras se desarrolla vara de
entorno a entorno. En la siguiente figura se muestra una comparacin entre la forma de estructurar el
proyecto segn Eclipse 3.1 y segn WebSphere 5.
Servlets
Un Servlet es un componente web, una clase que implementa la interfaz javax.servlet.Servlet. Esta
interfaz define mtodos para el ciclo de vida del programa, para obtencin de informacin del mismo,
y para brindar un "servicio". Para minimizar el esfuerzo de implementar esta interfaz, J2EE provee una
Pgina 54 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
clase abstracta que brinda mtodos por defecto, y adapta la interfaz a un protocolo puntual. Un
Servlet HTTP es una clase que no slo implementa esa interfaz sino que hereda de la clase
javax.servlet.http.HttpServlet.
Todos los servlets deben figurar en el descriptor de despliegue del mdulo web. All se les asigna un
alias que relaciona una URL con la clase puntual del Servlet.
Tpicamente, un Servlet HTTP atiende las peticiones web a travs de varios mtodos. Ocurre que esta
clase divide el mtodo service() de Servlet en los mtodos doGet(), doPost(), doDelete(),
doOptions(), doPut() y doTrace(), de los cuales los ms utilizados son los dos primeros. El mtodo
doGet() que recibe las peticiones que usan formato GET, y el mtodo doPost, que atiende las
peticiones en formato POST. Generalmente se desea que el comportamiento del Servlet sea el mismo
en ambos casos, por lo que suele ponerse, en el cuerpo de uno de estos mtodos, una llamada al otro.
En un Servlet se pueden especificar las tareas necesarias durante su ciclo de vida (mtodos init() y
destroy()). No es que se diga cundo se instanciar, sino que al escribir el constructor, o el mtodo
destroy, se est diciendo qu se har cuando sea instanciado y cuando sea eliminado. Asimismo
pueden utilizarse "filtros" que se ubican como un entubamiento antes de la llamada a los mtodos de
servicio (doGet y doPost) del Servlet.
Desde un servlet podemos recuperar la informacin que se encuentra en el formulario inserto en el
objeto request. Esto se hace a travs del mtodo getParameter(String name).
Tambin podemos aadir informacin al objeto request, mediante el mtodo setAttribute(String
name, Object value). Asimismo, se puede aadir informacin al objeto session y al objeto
application (aunque este objeto recibe el nombre de ServletContext). Recordemos que el objeto
request es el que tiene el menor tiempo de vida: desde que el cliente hace una peticin hasta que
obtiene una respuesta a esa peticin. El objeto session "vive" desde que un cliente realiza su primera
peticin, hasta que la sesin expira; la sesin puede expirar por una sentencia explcita, o bien porque
transcurri el perodo de inactividad especificado en la aplicacin web. Finalmente, el objeto
ServletContext (application) existe desde que se inicia la aplicacin hasta que sta es finalizada (o
sea que el ciclo de vida es prcticamente concordante con el ciclo de vida del contenedor).
La forma de obtener estos objetos es:
// Obtencin del ServletContext (application)
ServletContext sc = this.getServletContext();
// o lo que es lo mismo
ServletContext sc2 = this.getServletConfig().getServletContext();
// Obtencin del objeto session (si no existe, devuelve null)
HttpSession ses = request.getSession(false);
// Obtencin del objeto session (si no existe, lo crea);
// idntico a utilizar getSession(true)
HttpSession ses2 = request.getSession();
En el otro sentido, si podemos aadir informacin a estos objetos con los mtodos setAttribute,
podemos consultar esta informacin con los mtodos Object getAttribute(String name), tanto
desde el Servlet como desde un JSP. Tambin se puede utilizar el mtodo removeAttribute(String
name) para quitar un atributo.
Existen varias formas de direccionar el trfico desde un Servlet hacia otro recurso web (Servlet o JSP).
La primera forma es obtener un objeto RequestDispatcher desde el objeto request.
RequestDispatcher rd = request.getRequestDispatcher("../std/fset.jsp");
Pgina 55 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Ntese que el objeto RequestDispatcher se relaciona con el recurso destino al momento de crearse.
Una vez que tenemos este objeto, llamamos al mtodo forward del mismo pasando como parmetros
los objetos request y response con los que estuvimos trabajando en el Servlet.
rd.forward(request, response);
Una alternativa a esta forma es obtener el objeto RequestDispatcher desde el objeto
ServletContext. En este caso, la URL con la que se relaciona el objeto slo podr ser una URL
absoluta (en el caso anterior puede ser absoluta o relativa).
RequestDispatcher rd =
this.getServletContext().getRequestDispatcher("/jsp/std/fset.jsp");
Finalmente, aparte de hacer un forward se puede hacer un redirect hacia el recurso de destino. En
este caso, lo que en realidad hacemos es devolver al cliente un cdigo especial en la respuesta,
indicando que el recurso no se encontraba en el servidor donde se estaba buscando, por lo que se lo
redireccionar hacia otro servidor. Como se advierte, esta forma tiene un alto costo de performance,
puesto que la peticin volver al cliente, y de all de dirigir de nuevo al servidor (al mismo o a otro),
por lo que debera evitarse. De todas formas, la manera de hacerlo es:
response.sendRedirect("/jsp/std/fset.jsp");
JSPs
La tecnologa JSP es una especializacin de los Servlets. Estn pensados para escribir la respuesta
HTML que se devolver al cliente. Anteriormente a su introduccin, los Servlets se encargaban de las
dos tareas: ejecutar lgica, y escribir la respuesta. Algo que recuerda a CGI, pero que tiene como
problema que mezcla cdigo Java con HTML, reduciendo la legibilidad del archivo y volvindolo grande
y, en casos extremos, muy dificil de entender y mantener.
PrintWriter pw = response.getWriter();
pw.write("<html><head>");
Estas fueron las razones para que se creara un componente que se compila tal como en Servlet (slo
que se compila y ejecuta dinmicamente al recibir la primera peticin), pero que se ve como un
documento HTML. Otra ventaja de esto es que el rol de maquetador de pginas Web no necesita saber
Java.
Cada pgina es automticamente compilada a un Servlet por el motor de JSP la primera vez que esa
pgina es solicitada. Una vez que se compila, se ejecuta y el cdigo compilado queda a disposicin del
contenedor por si reciba nuevamente una peticin a esa pgina. El cdigo compilado se desechar
cuando el contenedor lo estime necesario.
Una pgina JSP es archivo de texto simple que consiste en contenido HTML o XML con elementos JSP.
El cdigo fuente de una pgina JSP incluye:
Directivas: Dan informacin global de la pgina, por ejemplo, importacin de clases, pgina
que majena los errores, bibliotecas de tags que se utilizarn, etc.
Scripts de JSP: Es el cdigo Java embebido en la pgina (se llaman Scriptlets).
Expresiones de JSP: Formatea las expresiones como cadenas para incluirlas en la pgina de
salida.
Cdigo HTML y Javascript: muestra textualmente el cdigo que se enviar en la respuesta.
Pgina 56 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Una directiva de JSP es una declaracin que proporciona la informacin del motor de JSP para la
pgina que la pide. Su sintaxis general es:
<%@ directiva {atributo ="valor"} %>
dnde la directiva debe tener un nmero de atributos. Por ejemplo:
<%@ page import="java.util.Vector, java.math.BigDecimal" %>
En realidad, lo que ocurre es que se estn seteando atributos (por ejemplo, el atributo import) de un
objeto (por ejemplo, el objeto page). Otras directivas aparte de page son "include", para incluir
archivos completos palabra por palabra, y "taglib", para incluir bibliotecas de etiquetas personalizadas.
Para la directiva "page", otros atributos aparte de import son "errorPage", que indica la URL de la
pgina que manejar las excepciones de JSP, y el atributo "isErrorPage", un booleano que indica si se
trata de una pgina de error o de una pgina comn.
Los Scriptlets son bloques de cdigo Java residentes entre los tags <% y %>.
Hay algunos objetos implcitos disponibles para los Scripts desde entorno del Servlet. Vamos a verlos
a continuacin:
Finalmente, las expresiones son una magnifica herramienta para insertar cdigo embebido dentro de
la pgina HTML. Cualquier cosa que este entre los tags <%= y %> ser evaluado, convertido a
cadena y posteriormente mostrado en pantalla. La conversin desde el tipo inicial a String es
manejada autmaticamente.
Cuando se trabaja con archivos JSP, es crucial entender cabalmente los ditintos tiempos en los que se
ejecutar la pgina. Primero existe el tiempo en que el motor compila la pgina. Para este tiempo es
imprescindible realizar todas las importaciones necesarias. Luego viene el tiempo de ejecucin de la
pgina, donde se ejecutarn todos los Scriptlets y se evaluarn las expresiones, formando as un nico
documento HTML de respuesta. Este documento debe contener toda la informacin necesaria para el
tercer tiempo de ejecucin. El ltimo tiempo de ejecucin es cuando la respuesta llega al cliente, y el
cliente interacta con ella a travs de JavaScript.
Pgina 57 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Desde una pgina JSP podemos dirigirnos a otro componente enviando el formulario que
generalmente se encuentra dentro de ella (haciendo un submit desde JavaScript), o bien modificando
la direccin del objeto location.href, aunque de esta ltima forma no dispondremos del formulario.
Para finalizar, cuando trabajo en esta capa recomiendo:
Utilizar slo un formulario por pgina. Son realmente pocas las veces en que necesitamos ms
de un formulario. Entonces, dejemos la complejidad y suciedad de los mltiples formularios
para los casos estrictamente necesarios.
Utilizar como nombre de formulario una palabra corta y representativa. Mi nombre favorito es
"fo".
Cerrar TODAS las etiquetas HTML, como si se tratase de XML (donde s es obligatorio cerrar
todos los tags). De esta forma nos ahorramos problemas con errores muy simples.
Hacer el submit de un formulario por JavaScript. Aparte de ser necesario la mayora de las
veces, el cdigo queda ms mantenible.
Utilizar el mtodo POST en vez del mtodo GET. De esta forma evitamos mostrar en la caja de
direccin del browser la informacin interna de la aplicacin.
Al igual que el segundo punto de esta lista, esta recomendacin es para aplicar no slo en
pginas JSP sino en todo el cdigo que realicemos: INDENTAR !.
Taglibs
Cuando programamos pginas JSP existen Scriptlets que se utilizan muy a menudo. Por ejemplo,
hacer un Scriptlet para un bucle for, o para un if, o una expresin JSP para recuperar un valor.
Es interesante la idea de utilizar tags o etiquetas para llevar a cabo estas funciones de lgica, porque
dejan ms limpio y legible el cdigo, y porque quitan del desarrollador de pginas JSP la
responsabilidad de saber Java. Pinsese en que es comn que a esta tarea de escritura del JSP la
realicen diseadores grficos. Entonces, el tiempo y costo que se ahorra una empresa por no necesitar
que los desarrolladores JSP conozcan Java es muy considerable.
Para ello, SUN provey las APIs necesarias para que todos pudiramos escribir las bibliotecas de tags
que considersemos necesarias en nuestro proyecto. Y adems, ofreci un conjunto de bilbiotecas
"estndar", el JSTL (JSP Standard Tag Library) que nos proporcionan las funcionalidades ms
comunes.
La JSTL se encuentra implementada por SUN y por el proyecto Jakarta de Apache.
Para utilizar una taglib es necesario utilizar la directiva taglib en el archivo JSP. Esta directiva
establece con un prefijo a utilizar en las llamadas a los tags de la biblioteca, y una URI donde se
encuentra definida. Adems, puede ser necesario incluir algunos .jar al proyecto, y/o archivos tld que
contienen el conjunto de tags definidos por el .jar. Tambin puede ser necesario declarar los taglibs
utilizados por la aplicacin en el archivo web.xml.
Por ejemplo, en el JSTL se encuentran definidas cuatro bibliotecas para manejo de XMLs, de SQL, de
formateo y de estructuras de control y repetitivas. Este ltimo conjunto se denomina "core". Para
disponer de l basta con incluir unos archivos denominados jstl.jar y otro llamado standard.jar. Luego,
se utiliza una directiva como:
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
y ya se pueden utilizar los tags:
<c:if test='${error != null}'>
<h1>Error de login</h1>
</c:if>
Pgina 58 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Adems, en este caso se est utilizando Expression Language (EL) dentro del atributo test para
acceder al atributo error (un atributo definido por el usuario) del objeto request sin necesidad de
utilizar un Scriptlet.
JNDI
El Java Naming & Directory Interface es el framework de Java que, similarmente a la funcin de JDBC,
proporciona una interfaz estndar para los servicios de nombres y de directorios existentes. Estos
servicios son muchos y muy variados, pero en general se caracterizan por publicar un nombre como
referencia a un recurso. Este recurso podra ser desde una simple variable hasta un archivo o una
impresora, pasando por una clase o ben una interfaz.
Los nombres JNDI se registran generalmente en la confiuracin del servidor, aunque podran aadirse
nombres JNDI desde el cdigo.
Desde la aplicacin, para buscar un nombre primero debemos partir de un contexto. Si ese contexto
es el del servidor actual, simplemente podemos crear un objeto InitialContext llamando al constructor
por defecto:
InitialContext ctx = new InitialContext();
Si no fuera as, debemos construir el objeto utilizando un objeto Properties (que contiene un HashMap
por debajo) con las propiedades del contexto que deseamos instanciar. Por ejemplo, para indicar la
clase factory del contexto, y la URL del proveedor (esto es, del servidor donde se buscarn los
nombres), se podra utilizar:
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
props.put(Context.PROVIDER_URL, "192.168.1.73:1099");
InitialContext ctx = new InitialContext(props);
Desde la aplicacin, buscar un nombre es sumamante simple. Basta con utilizar el mtodo lookup del
contexto. Este mtodo devuelve un Object, por lo que ser necesaro un casting hacia la clase
adecuada:
DataSource ds = (DataSource) ctx.lookup("jdbc/mysqlDS");
DataSources
Un DataSource es un objeto capaz de devolver conexiones a una base de datos puntual. Las
conexiones que devuelve son ms bien "lgicas", pues en realidad establecer slo UNA conexin real
con el servidor de datos, y sobre ella har un "pool" o lista de conexiones.
Un DataSource se configura en el servidor, sea a travs de una interfaz grfica, o bien directamente
modificando los archivos de configuracin del servidor puntual.
Aparte de la mejora de rendimiento, la idea era lograr que la configuracin de la base de datos a la
que debe comunicarse una aplicacin sea independiente de la aplicacin en s; de esta forma, se
puede cambiar de un motor a otro sin necesidad de tocar (y recompilar y re-desplegar) una sla lnea
de cdigo Java.
EJBs (2.0)
Pgina 59 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Un Enterprise Java Bean es un componente de servidor, generalmente encargado de la lgica de
negocio de una aplicacin. A partir de aqu, utilizar la palabra "bean" para referirme a los EJBs, que
nada tienen que ver con JavaBeans, unos componentes reutilizables, no de servidor, y pensados
principalmente para el uso de "reflection", la tcnica de deducir la estructura de un objeto en tiempo
de ejecucin. Los EJBs deben ser implementados en un proyecto EJB y ejecutarse en un contenedor
EJB apropiado.
Existen tres tipos bsicos de beans, los de sesin, los de entidad, y los manejados por mensajes. Los
dos primeros son sncronos, o sea que al realizarse una peticin (una llamada a un mtodo) el cliente
espera la respuesta para continuar con su cdigo. Los manejados por mensajes son asncronos, el
cliente enva un "mensaje" al bean y contina con su cdigo sin esperar la respuesta.
Los beans de entidad representan las clases de entidad del negocio. Podra parecer una redundancia
pero no lo es: el concepto de entidad es anterior a los beans, y excede los lineamientos de este curso.
Simplemente podemos decir que si necesitamos guardar la informacin de una clase en la base de
datos, entonces estamos tratando con una entidad. A esto de guardar la informacin de un objeto en
la base de datos se denomina "persistencia" del objeto. La persistencia puede estar a cargo del
contenedor (container managed persistance) o bien a cargo del mismo bean (bean managed
persistance).
Por otro lado, las clases pueden ser gestores. En este caso no contienen informacin que interese
directamente al negocio como las entidades, sino que estas clases tienen como fin cordinar el trabajo
de otras clases, sean estas de entidad o bien otros gestores. Estas clases se modelan a travs de los
Session Beans. Existen dos tipos de SB: los que guardan informacin de las peticiones que
antendieron en el pasado (son los beans "con estado", o stateful) y los que no ("sin estado", o
stateless).
Stateless
Session Beans
Stateful
BMP
EJB
Entity Beans
CMP
Si bien la forma de trabajo vara segn estemos utilizando un tipo de bean u otro, para la
instanciacin de un bean segn la especificacin 2.0 se utilizan dos interfaces y una clase. Las
interfaces son la "inicial" o home, y la remota. Cuando se desea utilizar un bean, lo primero a hacer es
obtener una instancia de la interfaz Home utilizando JNDI. Esto de una "instancia de la interfaz" es la
forma simplificada de decir que en el proveedor se crea un objeto y al cliente se devuelve la interfaz,
similar al trabajo que se realiza en JDBC o con WebServices. La obtencin de la referencia no puede
Pgina 60 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
recurrir a un casting explcito como se vi con DataSources, sino que es necesario utilizar el mtodo
esttico narrow de la clase PortableRemoteObject:
InitialContext ctx = new InitialContext();
Object ref = ctx.lookup("ejb/com/ini/ValidateHome");
ValidateHome valHome = (ValidateHome) PortableRemoteObject.narrow(ref,
ValidateHome.class);
Una vez que tenemos la interfaz Home, llamando al mtodo create() obtenemos una interfaz
Remote, ligada a una instancia de la clase del bean en el servidor. Desde esta interfaz Remote
podemos llamar a los mtodos de negocio del bean.
Validate val = valHome.create();
Integer empId = val.validarLogin(usr, pwd);
El ciclo comentado se muestra en la siguiente figura:
En general, los nombres de las clases y las interfaces siguen una nomenclatura fija. Si el bean se
llamase Empleado, la interfaz remota se llamar simplemente Empleado, la clase de implementacin
del bean se llamar EmpleadoBean, y la interfaz Home se llamar EmpleadoHome.
Cuando el bean se encuentra en el mismo contenedor desde donde se lo quiere utilizar, se utilizan
interfaces locales (EmpleadoLocalHome sera la interfaz Home y EmpleadoLocal sera la interfaz
remota).
Recordemos que los EJBs fueron pensados para ser consumidos no slo desde programas Java, sino
desde cualquier programa que pueda adaptarse al estndar CORBA.
Otra particularidad de los beans es que estn pensados para ser consumidos remotamente. Para ello,
el cliente debe contar con las interfaces, que se empaquetan en un archivo JAR de cliente EJB.
La seguridad para el acceso al bean suele quedar a cargo del contenedor, especificndosela en el
descriptor de despliegue (ejb-jar.xml, en este caso).
WebServices
Pgina 61 de 62
walter.a.montesano@accenture.com
Manual de Java + J2EE
Un WebService es un mtodo que puede ser invocado remotamente. El concepto viene de la
arquitectura SOA (Service Oriented Architecture), implementada por Microsoft a travs de estos
"WebServices". O sea que esta tecnologa no tiene relacin con J2EE, salvo porque puede ser
implementada en aplicaciones que siguen el modelo J2EE.
Un WebService puede estar implementado en una variedad de lenguajes, as como el cliente que lo
consume, siempre que en esta comunicacin se utilice el protocolo SOAP (Simple Object Access
Protocol).
Si bien con RMI primero, y con los EJB despus, ya era posible llamar a mtodos de objetos remotos
en Java, con los WebServices se maximiza la simplicidad y la independencia entre las aplicaciones
proveedor y cliente, puesto que la interfaz que debe conocer el cliente es slo un archivo XML,
puntualmente el WSDL, o WebService Description Language (ntese que el acrnimo no designaba en
principio al archivo, sino al lenguaje; pero en el uso corriente, con ese nombre se designa al archivo
de descripcin puntual de un WebService). En cambio, cuando se trabaja con EJBs, el cliente debe
conocer dos interfaces Java, an cuando no es obligatorio que el cliente en s est programado en este
lenguaje.
El WebService puede concebirse para ser consumido desde una aplicacin local, desde una intranet, o
bien desde la internet. Al ser utilizado remotamente, desde la intranet o desde internet, se debe
utilizar un "proxy" que rutear las llamadas que se dirigen a la interfaz del cliente hacia el objeto
remoto. Adems, cuando se lo desea publicar hacia la internet, es necesario utilizar algn servicio de
directorio como bien puede ser UDDI.
Pgina 62 de 62