Professional Documents
Culture Documents
ENCICLOPEDIA CONOCIENDO
ELABORADO POR: LUIS FELIPE WANUMEN SILVA INGENIERO DE SISTEMAS, CATLICO Y AUTOR DE LA ENCICLOPEDIA CONOCIENDO
CONTIENE CONCEPTOS, EJEMPLOS DE JSP, SERVLETS, BEANS, SOCKETS EJEMPLOS DE REDES Y ALGO MS.
Se empaquetan en un archivo EAR Se empaquetan en un archivo Se empaquetan en un archivo JAR Pagina WAR Clases Interfaces del Servlet html del Bean Bean
En el cuadro anterior podemos apreciar algunos componentes que se usan para la construccin de aplicaciones. Especficamente en el caso del cuadro anterior vemos que las pginas html y los servlet puden ser empaquetados en un archivo WAR, de otra parte las clases del Bean y las interfaces del Bean pueden ser empaquetadas en un archivo JAR y finalmente el archivo WAR y el archivo JAR se empaquetan en un archivo EAR. Para comprender mejor esta arquitectura diremos que una pgina html por lo general enva datos a un servlet, el servlet enva datos al Bean, el bean procesa las solicitudes, devuelve los resultados al servlet y el servlet crea una pgina html para mostrarle al cliente.
Enciclopedia Conociendo
El servlet es el siguiente:
import import import import javax.servlet.*; javax.servlet.http.*; java.io.*; java.sql.*;
public class saludos extends HttpServlet { ResultSet rs; Connection conexion_access; Statement sentencia; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out; String todo=""; try { Enciclopedia Conociendo Curso de Jsp y Servlets
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); String ruta1 = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=lucho.mdb"; conexion_access=DriverManager.getConnection("jdbc:odbc:luchodb" ,"",""); sentencia = conexion_access.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,Resul tSet.CONCUR_READ_ONLY); rs = sentencia.executeQuery("select * from estudiante"); todo = "<html>"; todo = todo + "<body>"; todo = todo + "<table>"; while(rs.next()){ todo = todo + "<tr>"; todo = todo + "<td>"; todo = todo + rs.getInt(1); todo = todo + "</td>"; todo = todo + "<td>"; todo = todo + rs.getString(2); todo = todo + "</td>"; todo = todo + "</tr>"; } // Cierra while todo = todo + "</table>"; todo = todo + "</body>"; todo = todo + "</html>"; } // Cierra try catch( Exception e ) { todo = "Hubo errores conectando a lucho.mdb"; return; } // Cierra catch resp.setContentType("text/html"); out = resp.getWriter(); out.println(todo);
} }
Enciclopedia Conociendo
<html> <head> <title>Mi primera insercion</title> </head> <body> <center> <form name="f1" action="servlet/inser" method="post"> <table> <tr> <td>Codigo </td> <td><input type=text name=c_cod> </td> </tr> <tr> <td>Nombre </td> <td><input type=text name=c_nom> </td> Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva </tr> <tr> <td> <input type=reset name=b_can value="cancelar"> </td> <td> <input type=submit name=b_ace value="insertar"> </td> </tr> </table> </form> </center> </body> </html>
en la que el usuario puede escribir el cdigo de un estudiante y el nombre. Cuando el usuario haga clic sobre el botn con el label denominado insertar se llama al servlet denominado inser. Para nuestro ejercicio supongamos que el usuario digita los siguientes datos:
Enciclopedia Conociendo
Cuando el usuario haga clic sobre el botn insertar, se llama al servlet denominado inser y se le pasan los datos digitados por el usuario. Veamos pues el cdigo fuente del servlet:
import import import import javax.servlet.*; javax.servlet.http.*; java.io.*; java.sql.*;
public class inser extends HttpServlet { ResultSet rs; Connection conexion_sql; Statement sentencia; Connection conexion_sql1; PreparedStatement sentencia1; public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conexion_sql1=DriverManager.getConnection( "jdbc:odbc:luchodb", "sa","" ); String in = "insert into estudiante values(?,?)"; sentencia1 = conexion_sql1.prepareStatement(in); sentencia1.clearParameters(); String x1 = req.getParameter("c_cod"); int x2 = Integer.parseInt(x1); String x3 = req.getParameter("c_nom"); sentencia1.setInt(1, x2); Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva sentencia1.setString(2, x3); sentencia1.executeUpdate(); sentencia1.close(); conexion_sql1.close(); } // Cierra try catch( Exception e ) { return; } // Cierra catch PrintWriter out; String todo="";
try { Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); conexion_sql=DriverManager.getConnection( "jdbc:odbc:luchodb"," sa","" ); sentencia = conexion_sql.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSe t.CONCUR_READ_ONLY); rs = sentencia.executeQuery("select * from estudiante"); todo = "<html>"; todo = todo + "<body>"; todo = todo + "<table>"; while(rs.next()){ todo = todo + "<tr>"; todo = todo + "<td>"; todo = todo + rs.getInt(1); todo = todo + "</td>"; todo = todo + "<td>"; todo = todo + rs.getString(2); todo = todo + "</td>"; todo = todo + "</tr>"; } // Cierra while todo = todo + "</table>"; todo = todo + "</body>"; todo = todo + "</html>"; rs.close(); sentencia.close(); conexion_sql.close(); } // Cierra try catch( Exception e ) { todo = "Hubo errores conectando a lucho.mdb"; return; } // Cierra catch resp.setContentType("text/html"); out = resp.getWriter(); out.println(todo); Enciclopedia Conociendo Curso de Jsp y Servlets
Observemos que en este caso no hay un mtodo doGet, sino que hay un mtodo doPost, y esto se debe a que el formulario enviaba los datos usando el mtodo post y se hace necesario recibir los datos con este mtodo que es el apropiado para recibir cuando son enviados de esta forma. De otra parte es bueno que el amigo lector / estudiante comprenda que el primer bloque try-catch se hace para insertar el dato y el segundo bloque try-catch se hace para mostrar los datos de la tabla. En el caso del ejercicio suponemos que existe una base de datos denominada colegio, la cual contiene a su vez una tabla llamada estudiante con los siguientes datos:
CODIGO 1 2 3 4 5 NOMBRE Luis Felipe Ana Esmeralda Natalia Paris Sofia Vergara Claudia Bahamon
De otra parte supongamos que tenemos un origen de datos en el sistema denominado luchodb. Esto har que nuestra variable conexin_sql1 quede direccionada a dicho orgen de datos y nos permita manipular la base de datos a la que hace referencia dicho orgen de datos. En este caso particular nuestro orgen de datos est con una base de datos en sql server 7.0 cuyo nombre de usuario es sa y de password no se le ha colocado valor alguno.
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); conexion_sql1=DriverManager.getConnection( "jdbc:odbc:luchodb", "sa","" );
Dichas instrucciones estn diciendo que se va a crear una variable denominada sentencia1, la cual es una sentencia preparada. Pero bueno, para aquellos lectores / estudiantes que no comprendan lo que es una sentencia preparada, a continuacin se dirn unas cosas al respecto. Primero que todo las sentencias preparadas, son sentencias que reciben parmetros. Esta es la razn por la cual la sentencia se ha definido de la forma: Insert into estudiante values (?,?)
Enciclopedia Conociendo
10
En la cual el primer parmetro que se pase ms adelante ser recibido por la sentencia y reemplazado por el primer signo ? que aparezca. Mas adelante se espera que sta sentencia reciba otro parmetro y dicho parmetro ser reemplazado por el segundo signo ? que aparezca. Con esto bien claro, pasemos a ver las siguientes instrucciones:
sentencia1.clearParameters(); String x1 = req.getParameter("c_cod"); int x2 = Integer.parseInt(x1); String x3 = req.getParameter("c_nom"); sentencia1.setInt(1, x2); sentencia1.setString(2, x3);
Obviamente segn todo lo dicho, podemos ver que estas instrucciones estn pasando el cdigo digitado por el usuario en la pgina como primer parmetro, obviamente despus de convertirlo a entero. Observe amigo lector / estudiante que el primer parmetro se pasa con la instruccin setInt, dado que en la base de datos es un campo entero. De otra parte el segundo parmetro se pasa con la instruccin setString, dado que es un campo de tipo nvarchar. Observe nuevamente amigo lector como Java se encarga de convertir los tipos de datos Java a tipos de datos de la base de datos. Por ltimo se ejecuta la sentencia con la instruccin:
sentencia1.executeUpdate(); sentencia1.close(); conexion_sql1.close();
En donde adems se cierran las conexiones. Bueno y el otro try-catch ya lo habamos explicado y lo que es mostrar los datos. Para el caso grfico vemos pues los resultados de nuestro ejercicio:
Enciclopedia Conociendo
11
Enciclopedia Conociendo
12
public class paginame extends HttpServlet { ResultSet rs; Connection conexion_access; Statement sentencia; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { int actual = 4; String actualin = req.getParameter("ac"); if(actualin==null){ actual = 1; } else{ actual = Integer.parseInt(actualin); Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva } PrintWriter out; resp.setContentType("text/html"); out = resp.getWriter(); out.println("<h1>Hello World</h1>"); out.println("La pagina actual es "+actual+"<br>");
13
int numeroRegistros = 0; try { Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); conexion_access=DriverManager.getConnection("jdbc:odbc:conectorODBC", "sa",""); sentencia = conexion_access.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,Resul tSet.CONCUR_READ_ONLY); rs = sentencia.executeQuery("select * from usuario"); while(rs.next()){ numeroRegistros++; } // Cierra while(rs.next()) } catch(Exception e){ out.println("Han ocurrido errores"); } // Cierra try
int numeroRegistrosPorPagina = 4; int enlaces = 0; enlaces = (int)(numeroRegistros/numeroRegistrosPorPagina); if((enlaces*numeroRegistrosPorPagina)!=numeroRegistros){ enlaces++; } for(int j=1;j<=enlaces;j++){ out.println("<a href=http://localhost:8080/examples/servlet/paginame? ac="+j+">"+j+"</a>"); } int inferior; int superior; inferior = (actual*numeroRegistrosPorPagina) numeroRegistrosPorPagina + 1; if(actual == enlaces){ superior = numeroRegistros; } else{ Enciclopedia Conociendo Curso de Jsp y Servlets
14
out.println("<br>Inferior = " + inferior); out.println("Superior = " + superior+"<br>"); String todo=""; try { Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); conexion_access=DriverManager.getConnection("jdbc:odbc:conect orODBC","sa",""); sentencia = conexion_access.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,Resul tSet.CONCUR_READ_ONLY); rs = sentencia.executeQuery("select * from usuario where codigo>="+inferior+" and codigo <="+superior); todo = "<html>"; todo = todo + "<body>"; todo = todo + "<center>"; todo = todo + "<table border=6>"; while(rs.next()){ todo = todo + "<tr>"; todo = todo + "<td>"; todo = todo + rs.getInt(1); todo = todo + "</td>"; todo = todo + "<td>"; todo = todo + rs.getString(2); todo = todo + "</td>"; todo = todo + "</tr>"; } // Cierra while todo todo todo todo = = = = todo todo todo todo + + + + "</table>"; "</center>"; "</body>"; "</html>";
} // Cierra try catch( Exception e ) { todo = "Hubo errores conectando a lucho.mdb"; return; } // Cierra catch resp.setContentType("text/html"); out = resp.getWriter(); out.println(todo); } // Cierra doGet } // Cierra public class paginame
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva La ejecucin del programa produce un resultado similar al siguiente:
15
Enciclopedia Conociendo
16
Enciclopedia Conociendo
17
Enciclopedia Conociendo
18
Enciclopedia Conociendo
19
Enciclopedia Conociendo
20
Ahora hacemos una pagina que sea capaz de mostrar una caja de texto llamada buscar que permite al usuario ingresar el codigo a buscar. Todo esto dentro de un formulario que tambien contiene los
Enciclopedia Conociendo
21
botones basicos de cancelar y enviar que tiene un formulario comun y corriente. Es decir creamos una pagina con la apariencia siguiente:
El codigo fuente de esta pagina es el siguiente: <HTML> <BODY> <form action=http://localhost:8080/examples/servlet/Consultame> <table border = 3> <tr> <td>Digite Codigo a buscar</td> <td><input type=text name=buscar></td> </tr> <tr> <td><input type=reset value=cancelame></td> <td><input type=submit value=buscame></td> </tr> </table> </form> </BODY> </HTML> En este caso por ejemplo si el usuario digita el numero 1 es porque quiere buscar el usuario cuyo codigo correponde al numero 1. Despus de ingresado el codigo, el usuario presiona el boton con el rotulo buscame y obtiene un resultado similar al siguiente:
Enciclopedia Conociendo
22
Bueno, estos resultados se logran porque en el servidor hemos creado un servlet que es capaz de recibir los datos y hacer la consulta. El codigo completo de dicho servlet es el siguiente: import import import import javax.servlet.*; javax.servlet.http.*; java.io.*; java.sql.*;
public class Consultame extends HttpServlet { Connection objConeccion; PreparedStatement sentencia; ResultSet resultados; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out; resp.setContentType("text/html"); out = resp.getWriter(); out.println("<h1>Resultados de su busqueda</h1>"); String cadenac = "Driver={SQL Server};Description=sqldemo;SERVER=SITEL; WSID=SITEL; UID=sa;PWD=;DATABASE=hijo"; try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); out.println("Vemos hijo has podido cargar los drivers"); // objConeccion = DriverManager.getConnection("jdbc:odbc:dibd","sa",""); objConeccion = DriverManager.getConnection("jdbc:odbc:"+cadenac,"sa",""); Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva out.println("Andale que conoces la base de datos"); // sentencia = objConeccion.createStatement(); String consultaSQL = "select * from usuario where codigo
23
= ?";
sentencia = objConeccion.prepareStatement(consultaSQL, ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); String codigin = req.getParameter("buscar"); codigin = codigin.trim(); sentencia.setInt(1,Integer.parseInt( codigin )); resultados = sentencia.executeQuery(); // resultados = sentencia.executeQuery("select * from usuario"); out.println(" <table border = 3>"); out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" <td>"); CODIGO"); </td>"); <td>"); NOMBRE"); </td>"); <td>"); APELLIDO"); </td>"); <td>"); DIRECCION"); </td>"); <td>"); CORREO"); </td>"); <td>"); DIRECCION LARGA"); </td>");
while(resultados.next()){ out.println("<tr>"); int cod = resultados.getInt("codigo"); String nom = resultados.getString("nombre"); String ape = resultados.getString("apellido"); String dir = resultados.getString("direccion"); String cor = resultados.getString("correo"); String dil = resultados.getString("direccion_larga"); out.println(" <td>"); out.println(""+cod); Enciclopedia Conociendo Curso de Jsp y Servlets
24
out.println(" <td>"); out.println(""+nom); out.println(" </td>"); out.println(" <td>"); out.println(""+ape); out.println(" </td>"); out.println(" <td>"); out.println(""+dir); out.println(" </td>"); out.println(" <td>"); out.println(""+cor); out.println(" </td>"); out.println(" <td>"); out.println(""+dil); out.println(" </td>");
</table>"); } catch(Exception e){ out.println("Error DESCONOCIDO, espera a que te lo presente"); } } } En donde podemos apreciar que la variable cadenac tiene la cadena de coneccion String cadenac = "Driver={SQL Server};Description=sqldemo;SERVER=SITEL; WSID=SITEL; UID=sa;PWD=;DATABASE=hijo"; y no se ha usado coneccion usando DSN alguno, motivo por el cual se comentarea la instruccin: // objConeccion = DriverManager.getConnection("jdbc:odbc:dibd","sa",""); Observe que el recordset se crea de solo lectura: sentencia = objConeccion.prepareStatement(consultaSQL, ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); Se recibe el contenido de la caja de texto html String codigin = req.getParameter("buscar");
} out.println("
Enciclopedia Conociendo
25
Y como esto siempre se recibe como tipo string, lo que se hace es convertirlo a entero, debido a que en la base de datos este tipo de datos es entero. Esto se logra con las instrucciones: codigin = codigin.trim(); sentencia.setInt(1,Integer.parseInt( codigin )); En donde la variable codigin es entera. Luego se ejecuta la sentencia: resultados = sentencia.executeQuery(); Se imprimen los encabezados de la tabla html: out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" out.println(" <table border = 3>"); <td>"); CODIGO"); </td>"); <td>"); NOMBRE"); </td>"); <td>"); APELLIDO"); </td>"); <td>"); DIRECCION"); </td>"); <td>"); CORREO"); </td>"); <td>"); DIRECCION LARGA"); </td>");
y a continuacin se imprimen todos los registros que cumplen la condicion: while(resultados.next()){ out.println("<tr>"); int cod = resultados.getInt("codigo"); String nom = resultados.getString("nombre"); String ape = resultados.getString("apellido"); String dir = resultados.getString("direccion"); String cor = resultados.getString("correo"); String dil = resultados.getString("direccion_larga"); out.println(" <td>"); out.println(""+cod); out.println(" </td>"); Enciclopedia Conociendo Curso de Jsp y Servlets
26
out.println(" <td>"); out.println(""+nom); out.println(" </td>"); out.println(" <td>"); out.println(""+ape); out.println(" </td>"); out.println(" <td>"); out.println(""+dir); out.println(" </td>"); out.println(" <td>"); out.println(""+cor); out.println(" </td>"); out.println(" <td>"); out.println(""+dil); out.println(" </td>"); } out.println(" </table>");
Si se presenta algun problema con la coneccion o en alguna otra parte del programa, se ejecuta lo que se encuentra en el bloque match: catch(Exception e){ out.println("Error DESCONOCIDO, espera a que te lo presente"); }
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva public String contarRegistros(){ ResultSet rs=null; Connection conexion_access=null; Statement sentencia=null; int numeroRegistros = 0; try { Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
27
conexion_access=DriverManager.getConnection("jdbc:odbc:origenNueva"," ",""); sentencia = conexion_access.createStatement(); rs = sentencia.executeQuery("select * from estudiante"); while(rs.next()){ numeroRegistros++; } // Cierra while(rs.next()) } catch(Exception e){ return "-1"; } // Cierra try finally{ try{ rs.close(); conexion_access.close(); } catch(Exception e){ } return "" + numeroRegistros;
} } // Cierra public int contarRegistros() public String consultar(int infe, int supe){ int contador = 0; ResultSet rs=null; Connection conexion_access=null; Statement sentencia=null; String todo = ""; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conexion_access=DriverManager.getConnection("jdbc:odbc:origenN ueva","",""); sentencia = conexion_access.createStatement(); rs = sentencia.executeQuery("select * from estudiante"); todo = "<html>"; todo = todo + "<body>"; todo = todo + "<center>"; todo = todo + "<table border=6>"; while(rs.next()){ contador++; Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva if(contador>=infe && contador<=supe){ todo = todo + "<tr>"; todo = todo + "<td>"; todo = todo + rs.getInt(1); todo = todo + "</td>"; todo = todo + "<td>"; todo = todo + rs.getString(2); todo = todo + "</td>"; todo = todo + "</tr>"; } // Cierra if(contador) } // Cierra while todo = todo + "</table>"; todo = todo + "</center>"; todo = todo + "</body>"; todo = todo + "</html>"; } // Cierra try catch( Exception e ) { todo = "Hubo errores conectando a Nueva.mdb"; } // Cierra catch finally{ return todo; } // Cierra finally } // Cierra public void consultar() public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { int actual = 0; String actualin = req.getParameter("ac"); if(actualin==null){ actual = 1; } else{ actual = Integer.parseInt(actualin); } PrintWriter out; resp.setContentType("text/html"); out = resp.getWriter(); out.println("<h1>Paginacion con Servlets</h1>"); out.println("<h2>Con enlaces anterior y siguiente</h2>"); out.println("La pagina actual es "+actual+"<br>"); int numeroRegistros = 0; numeroRegistros = Integer.parseInt(contarRegistros()); int numeroRegistrosPorPagina = 4;
28
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva int enlaces = 0; enlaces = (int)(numeroRegistros/numeroRegistrosPorPagina); if((enlaces*numeroRegistrosPorPagina)!=numeroRegistros){ enlaces++; } if(actual>1){
out.println("<a href=http://localhost:8080/examples/servlet/Paginacion?ac="+(actual1)+">Anterior</a>");
29
} for(int j=1;j<=enlaces;j++){ out.println("<a href=http://localhost:8080/examples/servlet/Paginacion? ac="+j+">"+j+"</a>"); } if(actual<enlaces){ out.println("<a href=http://localhost:8080/examples/servlet/Paginacion?ac="+ (actual+1)+">Siguiente</a>"); } int inferior; int superior; inferior = (actual*numeroRegistrosPorPagina) numeroRegistrosPorPagina + 1; if(actual == enlaces){ superior = numeroRegistros; } else{ superior = (actual*numeroRegistrosPorPagina); }
out.println("<br>Inferior = " + inferior); out.println("Superior = " + superior+"<br>"); String todo=""; todo = consultar(inferior, superior); resp.setContentType("text/html"); out = resp.getWriter(); out.println(todo); } // Cierra doGet } // Cierra public class paginame Observe amigo lector que se implementan dos if adicionales, en los cuales se pregunta si la pagina actual es mayor que uno if(actual>1){
out.println("<a href=http://localhost:8080/examples/servlet/Paginacion?ac="+(actual1)+">Anterior</a>");
30
Esto obviamente con el fin de lograr que este enlace no se muestre si estamos en la primera pagina, es decir, si el caso es el que muestra la siguiente pantalla:
De otra parte el enlace con la etiqueta Siguiente se muestra gracias al codigo siguiente: if(actual<enlaces){ out.println("<a href=http://localhost:8080/examples/servlet/Paginacion?ac="+ (actual+1)+">Siguiente</a>"); } Y esto hace que se muestre en todos los casos, menos cuando estemos ubicados en la ultima pagina, tal como lo muestra el pantallaza siguiente:
Enciclopedia Conociendo
31
Observe amigo lector que si estamos ubicados en una pagina que no sea ni la primera ni la ultima, se muestran tanto el enlace de anterior como de siguiente tal como lo muestra la siguiente pantalla:
Enciclopedia Conociendo
32
Otra cosa importante de notar es que la funcion que muestra los resultados se hizo aparte de la funcion normal llamada GET y esto bsicamente para despejar un poco el codigo del metodo GET para que no quedase muy largo. Tambien es importante notar que aunque al cliente se le muestran unicamente un segmento de datos, el servidor realmente tuvo que recorrer todos los datos antes de mostrar solamente al cliente unos cuantos, esto obviamente se puede mejorar con el animo de disminuir el trabajo realizado por el servidor con cada consulta. De todas formas esto si lo que hace es disminuir la congestion de red, debido a que al cliente tan solo se le envian un segmento de datos y el flujo que pasa por la red, no es tan grande como si se enviasen todos los datos.
Enciclopedia Conociendo
33
import java.awt.*; import java.awt.event.*; import java.sql.*; public class MyApp extends Frame{ Connection conexion_sql; Statement sentencia=null; TextArea ta = new TextArea(1,3); String cadena = ""; ResultSet rs=null; public MyApp(){ add(ta); this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); // Carga el driver JDBC-ODBC try { // Se usa este driver cuando se encuentra instalado en el sistema // Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); Enciclopedia Conociendo Curso de Jsp y Servlets
34
// Si en el sistema no se encuentra instalado el driver, pero // tenemos el jar ubicado en // C:\OraHome_1\jdbc\lib\classes12.jar // Agregamos una referencia a este driver en el proyecto y // deberia funcionar la siguiente linea: DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); } catch( Exception e ) { System.out.println( "No se pudo cargar el puente JDBC-ODBC." ); System.out.println("error con la clase java"); return; } String driverOracle = ""; driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle driverOracle = driverOracle + + + + + + + + + + + + + + + + + + + + + + + + + "DRIVER=Oracle en Home1;"; "UID=scott;"; "TLO=O;"; "FBS=60000;"; "FWC=F;"; "CSR=F;"; "MDI=Me;"; "MTS=T;"; "DPM=F;"; "NUM=NLS;"; "BAM=IfAllSuccessful;"; "FRL=Lo;"; "GDE=F;"; "RST=T;"; "LOB=T;"; "FDL=10;"; "FRC=10;"; "QTO=T;"; "FEN=T;"; "XSM=Default;"; "EXC=F;"; "APA=T;"; "DBA=W;"; "DBQ=ORCL;"; "SERVER=ORCL"; // Linea Solucion
// driverOracle = driverOracle + "SERVER=athlon.paralela.local"; // Linea problema. // Cuando intentaba usar la anterior linea en vez de la linea llamada // linea solucion, obtenia que se conectaba y encontraba la tabla // que estaba consultando, pero a la hora de escribir la sentencia // getString o getInt para recuperar datos, obtenia un error que // decia que // el estado del cursor no era valido. Estaba convencido que el // problema Enciclopedia Conociendo Curso de Jsp y Servlets
35
que
// el // problema era esta linea que tenia una parte mal del driver. // Como conclusion podemos decir con toda confianza que no siempre // que la linea de conectividad funcione, es porque la cuestion va a // funcionar // bien, o es porque el driver de hecho tiene todos los elementos // bien, // si no que se pueden presentar algunos problemas mas adelante si el // driver tiene alguno de los parametros mal especificados. // // // // String ruta1 = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=Medicos.mdb"; String ruta1 = "jdbc:odbc:DRIVER=Microsoft ODBC for Oracle;UID=orcl;SERVER=athlon";
String ruta1 = "jdbc:odbc:"+driverOracle; try{ // Establece la conexin con la base de datos conexion_sql = DriverManager.getConnection(ruta1,"scott","12346789"); } // Cierra try catch( Exception e ) { System.out.println("error en el dsn"); System.out.println(e); return; } try{ sentencia = conexion_sql.createStatement(); System.out.println("Estoy antes del while"); rs = sentencia.executeQuery("select * from usuar"); /* if(rs==null){ System.out.println("rs es null"); } else{ System.out.println("rs NO es null"); } */ // System.out.println(rs.getInt(1)); System.out.println("Estoy antes 3 del while"); while(rs.next()){ System.out.println("Estoy dentro del while"); cadena = cadena + rs.getInt("CODIGO"); cadena = cadena + "\t"; cadena = cadena + rs.getString("NOMBRE"); Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva cadena = cadena + "\n"; } // Cierra while System.out.println("Estoy despues del while"); rs.close(); sentencia.close(); conexion_sql.close(); } // Cierra try catch( Exception e ) { System.out.println(e); return; } ta.setText(cadena); } // Cierra public MyApp() public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(600,600); f.setVisible(true); } // Cierra main } // Cierra class MyApp
36
Enciclopedia Conociendo
37
Enciclopedia Conociendo
38
Enciclopedia Conociendo
39
Cuando usamos el igual en la instruccin: <%=variable1%> En realidad estamos usando expresiones. En realidad las expresiones nos permiten ahorrarnos cdigo al momento de imprimir variables.
Enciclopedia Conociendo
40
Con lo cual vemos que algunos objetos de Java como por ejemplo los objetos de datos estn disponibles en una pagina jsp. Ahora veamos el siguiente ejemplo: ejemplo5.jsp Autor: Luis Felipe Wanumen Silva<br> Declarando variables<br> <%! int variable1 = 165; %> <%! int variable2 = 165; %> <%! int variable3 = 165; %> Variable 1=<%out.println(variable1);%><br> Variable 2=<%out.println(variable2);%><br> Variable 3=<%out.println(variable3);%><br> Que muestra que es posible imprimir usando la instruccin out.println(). La anterior pgina al ser vista desde el navegador produce el siguiente resultado:
Enciclopedia Conociendo
41
A manera de ejemplo y de refuerzo a continuacin se imprimen unos objetos de datos usando la instruccin out.println(): ejemplo6.jsp Autor: Luis Felipe Wanumen Silva<br> Imprimiendo variables<br> <%! String obj_cadena1; %> <%! Integer obj_entero1; %> <%! int var_entero1 = 165; %> <% obj_cadena1="Soy cadena 1"; %> <% obj_entero1=new Integer(123); %> <% var_entero1=654; %> <%out.println(obj_cadena1); %><br> <%out.println(obj_entero1); %><br> <%out.println(var_entero1); %><br> El cual produce el siguiente resultado:
Enciclopedia Conociendo
42
Autor: Luis Felipe Wanumen Silva<br> LA DIRECTIVA INCLUDE<br> <%@ include file="DatosLuisF.txt"%> La cual como podemos observar hace referencia a una pagina llamada "DatosLuisF.txt", la cual para nuestro ejemplo contiene las siguientes lineas:
Realmente la explicacin es bien sencilla. Lo que hace la pagina JSP es incluir el contenido de archivo "DatosLuisF.txt". Con lo cual el resultado de la ejecucin de la pagina JSP es el siguiente:
43
ejemplo8.jsp Autor: Luis Felipe Wanumen Silva<br> LA DIRECTIVA INCLUDE<br> <html> <body>Este es un cuerpo</body> </html> <%@ include file="pagina1.html"%> Y que la pagina que es incluida, o sea la pagina "pagina1.html" para nuestro caso, contiene el siguiente cdigo: "pagina1.html" <html> <table border = 3> <tr> <td>Celda1</td> <td>Celda2</td> </tr> <tr> <td>Celda3</td> <td>Celda4</td> </tr> <tr> <td>Celda5</td> <td>Celda6</td> </tr> </table> </html> Obtenemos un resultado similar al siguiente si lo ejecutamos en un navegador como Internet Explorer 6.0:
Enciclopedia Conociendo
44
Enciclopedia Conociendo
45
Es claro que este cdigo funcionara solo en algunos navegadores, pero en otros navegadores se pueden producir resultados inesperados
Enciclopedia Conociendo
46
<% Vector obj_Vector1 = new Vector();%> <% obj_Vector1.addElement("Luis "); obj_Vector1.addElement("Felipe "); obj_Vector1.addElement("Wanumen "); obj_Vector1.addElement("Silva"); out.println(obj_Vector1.elementAt(0)); out.println(obj_Vector1.elementAt(1)); out.println(obj_Vector1.elementAt(2)); out.println(obj_Vector1.elementAt(3)); %> El resultado de la ejecucin de la anterior pagina JSP es el siguiente:
Observe amigo lector / estudiante que si no se hubiera colocado la sentencia: <%@ page import="java.util.*; "%> No estara disponible la clase Vector de java, tal cual se muestra en la siguiente pagina: ejemplo10.jsp <% Vector obj_Vector1 = new Vector();%> <% obj_Vector1.addElement("Luis "); obj_Vector1.addElement("Felipe "); obj_Vector1.addElement("Wanumen "); obj_Vector1.addElement("Silva"); out.println(obj_Vector1.elementAt(0)); out.println(obj_Vector1.elementAt(1)); Enciclopedia Conociendo Curso de Jsp y Servlets
47
48
Tambin funciona, con lo cual podemos concluir que el uso del punto y coma al final de la importacin no es obligatorio.
Enciclopedia Conociendo
49
Enciclopedia Conociendo
50
<% String valor = request.getParameter("p"); out.println("Soy la pagina "+valor); out.println("<br>"); %> <a href=ejemplo1.jsp?p=1>1</a> <a href=ejemplo1.jsp?p=2>2</a> <a href=ejemplo1.jsp?p=3>3</a> <a href=ejemplo1.jsp?p=4>4</a> El ejercicio corriendo es:
Enciclopedia Conociendo
51
Enciclopedia Conociendo
52
53
Si la divisin es exacta, entonces dicho resultado es igual al numero de paginas a mostrar, en caso que no sea exacto, entonces al resultado se le suma uno y se obtiene el nmero de paginas a mostrar. Para comprender mejor este concepto veamos pues a nivel de cdigo la implementacin de lo que se dice: <% int tamano_paginacion = 4; int numero_registros = 29; String valor = request.getParameter("p"); int paginas_usuario = 0; out.println("Soy la pagina "+valor); out.println("<br>"); int auxiliar = (int)(numero_registros/tamano_paginacion); if((auxiliar * tamano_paginacion)== numero_registros){ paginas_usuario = auxiliar; } else{ paginas_usuario = auxiliar+1; } out.println("El numero de paginas a mostrar es "+paginas_usuario); %>
4.3. IMPRIMIR LOS HIPERENLACES NECESARIOS DE ACUERDO CON EL NUMERO DE PAGINAS DE USUARIO
Usando el numero de paginas de usuario se imprimen las referencias a la misma pagina, pero con valores de parmetros diferentes. Veamos: <% int tamano_paginacion = 4; int numero_registros = 29; String valor = request.getParameter("p"); int paginas_usuario = 0; out.println("Soy la pagina "+valor); out.println("<br>"); int auxiliar = (int)(numero_registros/tamano_paginacion); if((auxiliar * tamano_paginacion)== numero_registros){ paginas_usuario = auxiliar; } else{ paginas_usuario = auxiliar+1; } out.println("El numero de paginas a mostrar es "+paginas_usuario+"<br>"); for(int i=1;i<=paginas_usuario;i++){ out.println("<a href=ejemplo1.jsp?p="+i+">"+i+"</a>"); } Enciclopedia Conociendo Curso de Jsp y Servlets
54
Enciclopedia Conociendo
55
En la anterior grafica se aprecia que la pagina actual es la numero tres y el enlace anterior esta e la pagina dos. Tambin observamos que
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva Si el enlace esta en la pagina uno, el enlace anterior no existe.
56
Enciclopedia Conociendo
57
Podemos apreciar que si estamos en la ltima pgina, no vemos el enlace siguiente, pero si estamos en la pagina
Enciclopedia Conociendo
58
La pregunta es Cul es la fmula? La frmula para el calculo del registro inicial es: (Pagina actual * tamao paginacin) (tamao paginacin -1) Rompiendo parntesis, tenemos limite_inferior = actual*tamano_paginacion - tamano_paginacion+1; Y para el registro final tenemos en forma anlioga: limite_superior = actual*tamano_paginacion; A nivel de cdigo tenemos pues las siguientes mejoras: <% int tamano_paginacion = 4; int numero_registros = 29; String valor = request.getParameter("p"); int actual = Integer.parseInt(valor); int anterior = -1; int siguiente = -1; int paginas_usuario = 0; out.println("Soy la pagina "+valor); out.println("<br>"); int auxiliar = (int)(numero_registros/tamano_paginacion); int limite_inferior = 0; int limite_superior = 0;
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva if((auxiliar * tamano_paginacion)== numero_registros){ paginas_usuario = auxiliar; } else{ paginas_usuario = auxiliar+1; } out.println("El numero de paginas a mostrar es "+paginas_usuario+"<br>"); if(actual >1){ anterior = actual-1; out.println("<a href=ejemplo1.jsp?p="+anterior+">anterior</a>"); } for(int i=1;i<=paginas_usuario;i++){ out.println("<a href=ejemplo1.jsp?p="+i+">"+i+"</a>"); } if(actual<paginas_usuario){ siguiente = actual+1; out.println("<a href=ejemplo1.jsp?p="+siguiente+">siguiente</a>"); } out.println("<br>"); limite_inferior = actual*tamano_paginacion - tamano_paginacion+1; limite_superior = actual*tamano_paginacion; out.println("El registro inicial es"+limite_inferior); out.println("El registro final es"+limite_superior); %> Cuyos resultados para la primera pgina son:
59
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva Para la segunda pgina los resultados son:
60
Enciclopedia Conociendo
61
Enciclopedia Conociendo
62
Enciclopedia Conociendo
63
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva if((auxiliar * tamano_paginacion)== numero_registros){ paginas_usuario = auxiliar; exacta = 0; } else{ paginas_usuario = auxiliar+1; exacta = 1; } out.println("El numero de paginas a mostrar es "+paginas_usuario+"<br>"); if(actual >1){ anterior = actual-1; out.println("<a href=ejemplo1.jsp?p="+anterior+">anterior</a>"); } for(int i=1;i<=paginas_usuario;i++){ out.println("<a href=ejemplo1.jsp?p="+i+">"+i+"</a>"); } if(actual<paginas_usuario){ siguiente = actual+1; out.println("<a href=ejemplo1.jsp?p="+siguiente+">siguiente</a>"); } out.println("<br>"); limite_inferior = actual*tamano_paginacion - tamano_paginacion+1; limite_superior = actual*tamano_paginacion; out.println("El registro inicial es"+limite_inferior); if(actual==paginas_usuario){ if(exacta==0){ out.println("El registro final es"+limite_superior); } else{ limite_superior = numero_registros; out.println("El limite superior es "+limite_superior); } } else{ out.println("El registro final es"+limite_superior); } %> Con lo cual se mejora el pantallaza para la ltima pgina, la cual para el caso de nuestro ejercicio se muestra a continuacin:
64
Enciclopedia Conociendo
65
Enciclopedia Conociendo
66
Autor: Luis Felipe Wanumen Silva } out.println("<br>"); limite_inferior = actual*tamano_paginacion - tamano_paginacion+1; limite_superior = actual*tamano_paginacion; if(actual==paginas_usuario){ if(exacta!=0) limite_superior = numero_registros; } try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:odbc:conector_access","",""); sentencia_preparada = con.prepareStatement("select * from estudiante where codigo>=? and codigo<=?"); sentencia_preparada.setInt(1, limite_inferior); sentencia_preparada.setInt(2, limite_superior); resultado = sentencia_preparada.executeQuery(); out.println("<br>"+"<table border= 5>"); while(resultado.next()){ out.println("<tr>"); out.println(" <td>"); out.println(""+resultado.getInt("codigo")); out.println(" </td>"); out.println(" <td>"); out.println(""+resultado.getString("nombre")); out.println(" </td>"); out.println("</tr>"); } out.println("</table>"); } catch(Exception e){ out.println("Se presentaron errores de BD"); } %>
67
Autor: Luis Felipe Wanumen Silva int actual = Integer.parseInt(valor); int anterior = -1; int siguiente = -1; int paginas_usuario = 0; out.println("Estas en la pagina "+valor); out.println("<br>"); int limite_inferior = 0; int limite_superior = 0; int exacta = 0; String consulta = ""; Connection con = null; PreparedStatement sentencia_preparada = null; Statement sentencia = null; ResultSet resultado = null; ResultSet resultado1 = null; int contador = 0; int tamano_paginacion = 4; int numero_registros = 29; try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:odbc:conector_access","",""); sentencia = con.createStatement(); resultado1 = sentencia.executeQuery("select * from estudiante"); while(resultado1.next()){ contador++; } numero_registros = contador; } catch(Exception e){ out.println("Error contando registros de BD"); } int auxiliar = (int)(numero_registros/tamano_paginacion); if((auxiliar * tamano_paginacion)== numero_registros){ paginas_usuario = auxiliar; exacta = 0; } else{ paginas_usuario = auxiliar+1; exacta = 1; } if(actual >1){ anterior = actual-1; out.println("<a href=ejemplo1.jsp?p="+anterior+">anterior</a>"); } for(int i=1;i<=paginas_usuario;i++){ out.println("<a href=ejemplo1.jsp?p="+i+">"+i+"</a>"); } if(actual<paginas_usuario){ Enciclopedia Conociendo
68
Autor: Luis Felipe Wanumen Silva siguiente = actual+1; out.println("<a href=ejemplo1.jsp?p="+siguiente+">siguiente</a>"); } out.println("<br>"); limite_inferior = actual*tamano_paginacion - tamano_paginacion+1; limite_superior = actual*tamano_paginacion; if(actual==paginas_usuario){ if(exacta!=0) limite_superior = numero_registros; } try{ // Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:odbc:conector_access","",""); sentencia = con.createStatement(); resultado1 = sentencia.executeQuery("select * from estudiante"); while(resultado1.next()){ contador++; } numero_registros = contador; sentencia_preparada = con.prepareStatement("select * from estudiante where codigo>=? and codigo<=?"); sentencia_preparada.setInt(1, limite_inferior); sentencia_preparada.setInt(2, limite_superior); resultado = sentencia_preparada.executeQuery(); out.println("<br>"+"<table border= 5>"); while(resultado.next()){ out.println("<tr>"); out.println(" <td>"); out.println(""+resultado.getInt("codigo")); out.println(" </td>"); out.println(" <td>"); out.println(""+resultado.getString("nombre")); out.println(" </td>"); out.println("</tr>"); } out.println("</table>"); } catch(Exception e){ out.println("Se presentaron errores de BD"); } %>
69
Enciclopedia Conociendo
70
Enciclopedia Conociendo
71
5. ETIQUETAS JSP
Las etiquetas jsp permiten que una aplicacin java con paginas .jsp invoquen etiquetas al estilo html, pero que dichas etiquetas por algn mecanismo interno del servidor web se procesen al estilo java por medio de la ejecucin de unos programas que extienden de la clase TagSupport
72
que al interior de la carpeta classes debe existir otra carpeta llamada carpeta que a su vez contiene el archivo .class de nuestra etiqueta java, dicho archivo contiene el siguiente cdigo: TagMio1.java
package carpeta; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; public class TagMio1 extends TagSupport { private String nombre = null; // public void TagMio1() {} public void setNombre( String _nombre ) { nombre = _nombre; } public String getNombre() { return( nombre ); } public int doStartTag() throws JspTagException { try { JspWriter out = pageContext.getOut(); out.println( "<table border=1>" ); if( nombre != null ) { out.println( "<tr><td> Hola Tag Mio1" +nombre+ " </td></tr>" ); } else { out.println( "<tr><td>Hola Mundo de etiquetas JSP</td></tr>" ); } } catch( Exception e ) { throw new JspTagException( e.getMessage() ); } return( SKIP_BODY ); } public int doEndTag() throws JspTagException { try { pageContext.getOut().print( "</table>" ); } catch( Exception e ) { throw new JspTagException( e.getMessage() ); } return( SKIP_BODY ); } public void release() { super.release(); } }
En donde podemos observar que el metodo doStartTag() se ejecuta cuando la etiqueta se abre y el metodo doEndTag() se ejecuta cuando finaliza la etiqueta. Ahora
Enciclopedia Conociendo
73
Ahora bien para lograr que esta etiqueta sea til se necesita invocarla desde una pagina .jsp, a continuacin se muestra el cdigo fuente del archivo TagMio1.jspque invoca la etiqueta creada anteriormente: TagMio1.jsp <%@ taglib uri="/WEB-INF/tlds/etiquetillas.tld" prefix="etiquete" %> <html> <body> <p> <hr><center> <etiquete:TagMio1 nombre=" Luis Felipe"/> </center><hr> <etiquete:TagMio1 /> </body> </html> Observe que la etiqueta se llama TagMio1 pero esta referenciada con un prefijo llamado etiquete que pudo haber sido otra palabra, tambien observe que el parmetro nombre es invocado pasandole el valor de Luis Felipe y la otra vez no es invocado, con lo cual el programa se invoca y ejecuta dos veces.
74
</taglib> En donde se aprecia que solo existe un tag referenciado el cual se llama TagMio1 que se espera se encuentre en la carpeta llamada carpeta. El problema viene si se hace una pagina .jsp que intente ejecutar el siguiente cdigo: TagMio2.jsp <%@ taglib uri="/WEB-INF/tlds/etiquetillas.tld" prefix="etiquete" %> <html> <body> <etiquete:TagMio2 nombre="estudiante"/> </body> </html> Se produce un error similar al siguiente:
Y esto se debe a que el Tag TagMio2.java no existe y as se creara seguira producindose el error bsicamente debido a que el sistema no lo tiene referenciado en el archivo tipo .tld. Enciclopedia Conociendo Curso de Jsp y Servlets
75
Teniendo en cuenta que se ha creado una base de datos en SQL Server 2005 con una tabla llamada estudiante tal como muestra la siguiente figura:
Enciclopedia Conociendo
76
Para lograr este efecto se requiere crear nuevamente el archivo descriptor de etiquetas, en este caso vamos a crear un archivo llamado etiquetillas que contendr el siguiente cdigo: Etiquetillas.tld <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.2</jspversion> <shortname>capitulo6</shortname> <info> Librera de Etiquetas correspondiente al captulo 6 </info> <tag> <name>TagMio2</name> <tagclass>carpeta.TagMio2</tagclass> <bodycontent>empty</bodycontent> <attribute> <name>nombre</name> </attribute> </tag> </taglib> De tal suerte que podremos crear el archivo TagMio2.java con el siguiente cdigo: TagMio2.java
Enciclopedia Conociendo
77
import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; public class TagMio2 extends TagSupport { private String nombre = null; // public void TagMio1() {} public void setNombre( String _nombre ) { nombre = _nombre; } public String getNombre() { return( nombre ); } public int doStartTag() throws JspTagException { try { JspWriter out = pageContext.getOut(); if(nombre!=null){ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con; con = DriverManager.getConnection("jdbc:odbc:lucho","sa",""); Statement sen; sen = con.createStatement(); ResultSet rs; rs = sen.executeQuery("select * from "+nombre); while(rs.next()){ String dato2 = rs.getString("nombre"); out.println(dato2); } } // Cierra if } catch( Exception e ) { throw new JspTagException( e.getMessage() ); } return( SKIP_BODY ); } public int doEndTag() throws JspTagException { try { pageContext.getOut().print( "</table>" ); } catch( Exception e ) { throw new JspTagException( e.getMessage() ); }
Enciclopedia Conociendo Curso de Jsp y Servlets
78
De tal suerte que la invocacin del archivo TagMio2.java ubicado como muestra la siguiente figura:
Enciclopedia Conociendo
79
Podr ser invocado desde una pagina TagMio2.jsp usando el codigo fuente mostrado a continuacin: TagMio2.jsp <%@ taglib uri="/WEB-INF/tlds/etiquetillas.tld" prefix="etiquete" %> <html> <body> <etiquete:TagMio2 nombre="estudiante"/> </body> </html> Y produciendo unos resultados similares a los siguientes:
Enciclopedia Conociendo
80
Enciclopedia Conociendo
81
TAG.tld <?xml version="1.0" encoding="UTF-8"?> <taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"> <tlib-version>1.0</tlib-version> <short-name>tag</short-name> <uri>/WEB-INF/tlds/TAG</uri> <tag-file> <name>TARARCHIVO</name> <path>/WEB-INF/tags/TARARCHIVO.tag</path> </tag-file> </taglib>
Enciclopedia Conociendo
82
TAGARCHIVO.tag <%@tag description="put the tag description here" pageEncoding="UTF-8"%> <jsp:useBean id="Uno" class="tag.NewBean"/> <jsp:useBean id="Dos" class="tag.Bean1"/> <%-- The list of normal or fragment attributes can be specified here: --%> <%@attribute name="message"%> <%-- any content can be specified here e.g.: --%> <h2>${message}</h2> <% Dos.setCodigo(message); out.println(Dos.getNombre()); %>
Autor: Luis Felipe Wanumen Silva * @author microsoft */ import java.sql.*; public class Bean1 { private String nombre; Connection objCon; PreparedStatement objSen; ResultSet objRes; int codigo; String res=""; public void setNombre(String valor){ this.nombre = valor; } public void setCodigo(String valor){ codigo = Integer.parseInt(valor); } public String getNombre(){ try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); objCon = DriverManager.getConnection("jdbc:odbc:luchodb","sa",""); objSen = objCon.prepareStatement("select nombre from usuario1 where codigo = ?"); objSen.setInt(1,this.codigo); objRes = objSen.executeQuery(); while(objRes.next()){ res = res + objRes.getString("nombre"); } } catch(Exception e){ res = e.toString(); } return this.res; } }
83
Autor: Luis Felipe Wanumen Silva </head> <body> <h1>Hello World!</h1> <etiquete:TARARCHIVO message="2" /> </body> </html>
84
Enciclopedia Conociendo
85
Insert into usuario values(1,Hugo) Insert into usuario values(2,Paco) Insert into usuario values(3,Luis)
Enciclopedia Conociendo
86
Enciclopedia Conociendo
87
Creamos una tabla llamada estudiante con dos campos uno llamado codigo y otro llamado nombre
Enciclopedia Conociendo
88
Enciclopedia Conociendo
89
Enciclopedia Conociendo
90
Enciclopedia Conociendo
91
Enciclopedia Conociendo
92
Enciclopedia Conociendo
93
Enciclopedia Conociendo
94
Enciclopedia Conociendo
95
En nuestro ejercicio el proyecto lo llamamos: Udistrital y lo creamos con la especificacin J2EE 1.3
Enciclopedia Conociendo
96
En nuestro caso no vamos a usar ningun Framework es decir que no seleccionamos Framework alguno:
Enciclopedia Conociendo
97
7.4. PASO 4: CREACION DEL PAQUETE QUE TENDRA LA LOGICA Y EL ACCESO A DATOS
Al interior de un proyecto web NetBeans se tienen varias carpetas, y especficamente vamos a crear un paquete al interior de la carpeta Source Packages
Enciclopedia Conociendo
98
Una de las cosas mas tiles es empaquetar las clases y por eso vamos a crear un paquete nuevo llamado MiPaqueteChileno
Enciclopedia Conociendo
99
De tal manera que el paquete por defecto que se tiene en la carpeta Source Packages queda reemplazado por el paquete llamado MiPaqueteChileno
Enciclopedia Conociendo
100
Enciclopedia Conociendo
101
Llamada Registro
Enciclopedia Conociendo
102
Al interior del paquete llamado MiPaqueteChileno que controlara los eventos de ingresar, es decir que dentro del modelo vista controlador tendr la funcin de controlador. Y tambin creamos una clase en el mismo paquete llamada ConexionBd que manejara el modelo pues estar muy cerca de la persistencia y se encargara de los pequeos detalles relacionados con la conexin a la base de datos.
Enciclopedia Conociendo
103
Enciclopedia Conociendo
104
Enciclopedia Conociendo
105
Observe amigo lector / estudiante que NetBeans le coloca la extensin .jsp al archivo.
Autor: Luis Felipe Wanumen Silva } catch(Exception e){ System.out.println("No se puede realizar la conexin"); System.out.println(e); } return resp; } public ConexionBd() { super(); } public int Inserta (String sentencia){ int dat=0; if(conectaBd()){ try{ this.stt=this.con.createStatement(); dat=this.stt.executeUpdate(sentencia); this.stt.close(); this.con.close(); } catch(Exception e){ this.error="no se puedo realizar el insert a la bd"; } } // Cierra if return dat; } // Cierra Inserta public static void main(String[] args) { // TODO Auto-generated method stub ConexionBd c = new ConexionBd(); c.conectaBd(); } }
106
En donde se presenta un metodo llamado conectaBd() que se conecta con la base de datos mediante un origen de sistema llamado origen. Es importante notar que este Bean tiene el metodo main() y esto es valido debido a que este Bean no es un Bean Empresarial. (Algunos autores ni siquiera consideran que el anterior programa sea un Bean) Lo interesante del asunto es que la insercin de datos es manejada por la clase ConeccionBd() pero el lanzamiento de dicha insercin es manejada solamente desde una clase controladora llamada Registro.java Antes de explicar detenidamente la clase Registro.java mencionaremos que el metodo Inserta() es invocado desde afuera de la clase ConectaBd y se valida que su ejecucin se realice siempre y cuando se halla podido ejecutar el constructor de la clase y esto se logra con la pregunta: if(conectaBd()) De otra parte es importante mencionar que una vez se ingresan los datos se cierran las conecciones. Enciclopedia Conociendo Curso de Jsp y Servlets
107
108
amigo lector / estudiante comprenda que la parte de los metodos que comienza con get y con set son obligatorias si quiero que se presente un buen comportamiento al usar este Bean.
Enciclopedia Conociendo
109
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva Con la directiva <%@ page language="java" import="java.util.* %>
110
Se incorporan libreras y no es posible usar este tipo de inclusiones para incluir otros archivos que cambian o sean dinmicos. Cuando la pagina JSP recibe valores para las variables codigo, nombre y password nulos mediante las instrucciones getParameter("codigo") getParameter("nombre") getParameter("password") carga el formulario HTML siguiente: <form name="registro" method="POST" action="registro.jsp"> <p>Nombre</p><input type="text" name="nombre" /><br /> <p>Codigo</p><input type="text" name="codigo" /><br /> <p>Contrasea</p><input type="password" name="contrasenia"/><br /> <p><button type="submit">Enviar</button></p> </form> Pero cuando dichos valores no son nulos son recibidos por la variable registro la cual hace referencia al Bean Registro que se encuentra en el paquete MiPaqueteChileno y que se puede invocar desde la pagina jsp debido a que ya esta incluido con las siguientes instrucciones: <jsp:useBean id="registro" class="MiPaqueteChileno.Registro" scope="page"> <jsp:setProperty name="registro" property="*"></jsp:setProperty> </jsp:useBean> Observe amigo lector que la incorporacin de Bean en una JSP se puede hacer mediante etiquetas useBean En las etiquetas useBean se presentan algunos parmetros que es bueno que todos conozcamos: Id: Nombre con el cual el Bean es reconocido desde la pagina JSP Class: Nombre de la clase Bean que vamos a incorporar en nuestra JSP. Scope: Duracin de la referencia a este Bean. Otros tipos son: sesion, page, request y application, en nuestro caso estamos diciendo que la referencia a este Bean se pierde cuando se pasa a otra pagina jsp. La pregunta que se estara haciendo en este momento el amigo lector / estudiante es: en qu momento se estn pasando las variables al Bean?. La respuesta es bien sencilla: Al poner property="*" estamos diciendo que las variables en la clase se llaman igual que la interfaz y son pasadas en forma transparente a travs de los mtodos get y set al Bean.
111
En NetBeans no hay que saber mucho de ensamble y despliegue de aplicaciones, debido a que el hace todo este trabajo para el programador y por ello lo unico que se hara en NetBeans 6.0 es ejecutar:
Enciclopedia Conociendo
112
Enciclopedia Conociendo
113
Enciclopedia Conociendo
114
Con el metodo addCookie se adicionan las cookies. Mas adelante se usa el metodo getCookies() para obtener un vector de cookies y cada una de sus posiciones es una cookie que tiene dos propiedades que son Nombre y Valor que pueden se accedidas mediante los metodos getName() y getValue() de la clase Cookie. El ejemplo completo es el siguiente: import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class HelloWorldExample extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out; resp.setContentType("text/html"); out = resp.getWriter(); out.println("<h1>Mostrando Cookies</h1>"); Cookie c1 = new Cookie("Nombre1","Luis"); Cookie c2 = new Cookie("Nombre2","Felipe"); Cookie c3 = new Cookie("Apellido1","Wanumen"); Cookie c4 = new Cookie("Apellido2","Silva"); resp.addCookie(c1); resp.addCookie(c2); resp.addCookie(c3); resp.addCookie(c4); Cookie[] cookies = req.getCookies(); for (int i = 0; i < cookies.length; i++) { Cookie c = cookies[i]; Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva String name = c.getName(); String value = c.getValue(); out.println(name + " = " + value);
115
} } }
Enciclopedia Conociendo
116
Como quien dice, no hay resultados visibles, ya que se crea la session pero no se esta mostrando, para mostrar el contenido de la session basta con hacer una pagina jsp que invoque el metodo getAttribute() del objeto session, dicha pagina se muestra a continuacin: <%-Colocar valores en las sesiones --%> <%@page session="true"%> <% Object objetoRecibido = session.getAttribute("Nombre"); String cadena = (String)objetoRecibido; out.println(cadena); %> Al ejecutar la pagina anterior, obviamente habiendo ejecutado primero la pagina sesion1.jsp obtenemos el siguiente resultado:
Enciclopedia Conociendo
117
Enciclopedia Conociendo
118
Recordad que estos sockets inicialmente operan sobre TCP/IP EL OBJETIVO ES HACER UN CHAT En este momento estamos haciendo la parte del Servidor.
Enciclopedia Conociendo
119
De tal forma que cuando el usuario haga clic en la opcin Arrancar el Servidor, el sistema crear un ServerSocket que estar escuchando por el puerto 210
Enciclopedia Conociendo
120
String salida = "Hola"; byte[] bytes_enviados = salida.getBytes(); cliente = new Socket("xp",210); OutputStream envia = cliente.getOutputStream(); envia.write(bytes_enviados); System.out.println(new String(bytes_enviados));
Por ultimo las instrucciones del cliente se pueden colocar en una interfaz grfica similar a la siguiente:
De tal forma que cuando el usuario haga clic en la opcin Enviar, el sistema envie Hola al servidor. Ahora bien, con el nimo de lograr la mayor comprensin del tema por parte del amigo lector / estudiante, a continuacin se muestra el cdigo de la aplicacin que reside en el lado del servidor: Clase3.java
public class Clase3 { public static void main(String[] args) { // Create application frame. Clase3Frame frame = new Clase3Frame(); // Show frame. frame.show(); } }
Clase3Frame.java
import java.net.*;
Enciclopedia Conociendo Curso de Jsp y Servlets
121
/** * The constructor. */ ServerSocket ssock; public void arrancar() throws Exception { ssock = new ServerSocket(210); System.out.println("El servidor esta escuchando"); } public void aceptar() throws Exception{ Socket ap_cliente1 = ssock.accept(); System.out.println("Ha llegado un cliente"); InputStream recibir = ap_cliente1.getInputStream(); while(true){ int c = recibir.read(); if(c==-1) break; System.out.println((char)c); } } public Clase3Frame() { JMenuBar menuBar = new JMenuBar(); JMenu menuRedes = new JMenu(); JMenuItem menuRedesArrancar = new JMenuItem(); JMenuItem menuRedesExit = new JMenuItem(); menuRedes.setText("Redes"); menuRedesArrancar.setText("Arranque el servidor");
Enciclopedia Conociendo Curso de Jsp y Servlets
122
menuRedesExit.setText("Exit"); // A continuacion se asocia la opcion de menuItem // menuRedesArrancar con una accion menuRedesArrancar.addActionListener ( new ActionListener() { public void actionPerformed(ActionEvent e) { // System.out.println("Probando evento"); try{ arrancar(); aceptar(); } catch(Exception p){ } } } ); // Add action listener.for the menu button menuRedesExit.addActionListener ( new ActionListener() { public void actionPerformed(ActionEvent e) { Clase3Frame.this.windowClosed() ; } } ); menuRedes.add(menuRedesArrancar); menuRedes.add(menuRedesExit); menuBar.add(menuRedes); setTitle("Clase3Frame"); setJMenuBar(menuBar);
Enciclopedia Conociendo Curso de Jsp y Servlets
123
setSize(new Dimension(400, 400)); // Add window listener. this.addWindowListener ( new WindowAdapter() { public void windowClosing(WindowEvent e) { Clase3Frame.this.windowClosed() ; } } ); } /** * Shutdown procedure when run as an application. */ protected void windowClosed() { // TODO: Check if it is safe to close the application // Exit application. System.exit(0); } }
y el cdigo de la aplicacin que reside en el lado del cliente es: Clase4.java
public class Clase4 { public static void main(String[] args) { Clase4Frame frame = new Clase4Frame(); frame.show(); } }
Enciclopedia Conociendo Curso de Jsp y Servlets
124
public class Clase4Frame extends JFrame { Socket cliente; public void crear_cliente_y_envia() throws Exception{ String salida = "Hola"; byte[] bytes_enviados = salida.getBytes(); cliente = new Socket("xp",210); OutputStream envia = cliente.getOutputStream(); envia.write(bytes_enviados); System.out.println(new String(bytes_enviados)); } public Clase4Frame() { JMenuBar menuBar = new JMenuBar(); JMenu menuRedes = new JMenu(); JMenuItem menuRedesEnviar = new JMenuItem(); JMenuItem menuRedesExit = new JMenuItem(); menuRedes.setText("Redes"); menuRedesEnviar.setText("Enviar"); menuRedesExit.setText("Salir"); menuRedesEnviar.addActionListener ( new ActionListener() { public void actionPerformed(ActionEvent e) { try{
Enciclopedia Conociendo Curso de Jsp y Servlets
125
crear_cliente_y_envia(); } catch(Exception p){ } } } ); menuRedesExit.addActionListener ( new ActionListener() { public void actionPerformed(ActionEvent e) { Clase4Frame.this.windowClosed() ; } } ); menuRedes.add(menuRedesEnviar); menuRedes.add(menuRedesExit); menuBar.add(menuRedes); setTitle("Clase4Frame"); setJMenuBar(menuBar); setSize(new Dimension(400, 400)); this.addWindowListener ( new WindowAdapter() { public void windowClosing(WindowEvent e) { Clase4Frame.this.windowClosed() ; } } ); } protected void windowClosed() {
Enciclopedia Conociendo Curso de Jsp y Servlets
126
System.exit(0); } }
Cuando el Servidor detecta que ha llegado un cliente, lo que hace es atenderlo y recibe lo que ste le est enviando. Para el caso especfico de nuestro ejemplo, se tiene un resultado en trminos de ejecucin similar al siguiente:
que se presenta cuando se ejecuta la aplicacin cliente y se le da clic en el botn Enviar. Como el amigo lector / estudiante pudo observar, el anterior cdigo en esencia no es largo, lo que sucede es que el hecho de haberlo colocado en una interfaz agradable al usuario hace que sean necesarias la incorporacin de varias lneas, pero esto en ltimas es puro maquillaje de interfaz grfica. Lo que si debe ser claro para el lector es que el cdigo anterior se hizo en varios archivos para lograr que se tengan buenos hbitos de programacin y se trate de trabajar en forma modular y no como hacen muchas personas: todo el cdigo en un solo archivo. Espero que el ejercicio halla sido de agrado para el lector.
Enciclopedia Conociendo
127
128
import java.net.*; public class Cliente { public Cliente(){ try{ Socket objetoServidor = new Socket("localhost",80); System.out.println("Pude crear el objeto cliente"); } catch(Exception e){ System.out.println("No pude crear el objeto cliente"); } } // Cierra public Servidor() public static void main(String[] args) { System.out.println("Hola Soy el CLIENTE"); Cliente principal = new Cliente(); } }
Enciclopedia Conociendo
129
El programa mejorado en el lado del servidor es: import java.net.*; import java.io.*; public class Servidor { public Servidor(){ try{ ServerSocket objetoServidor = new ServerSocket(85); System.out.println("Pude crear el objeto servidor"); Socket refCliente = objetoServidor.accept(); System.out.println("Ha llegado el cliente "); InputStream entrada = refCliente.getInputStream(); DataInputStream carritoEntrada = new DataInputStream(entrada); String lectura = ""; lectura = carritoEntrada.readUTF(); System.out.println("Lo que me llego es "+lectura); } catch(Exception e){ System.out.println("Errores en el servidor"); } } // Cierra public Servidor() public static void main(String[] args) { System.out.println("Hola Soy el SERVIDOR"); Servidor principal = new Servidor(); } } El programa mejorado en el lado del cliente es: import java.net.*; import java.io.*; public class Cliente { public Cliente(){ try{ Socket objetoCliente = new Socket("localhost",85); System.out.println("Pude crear el objeto cliente"); // Esto crea un flujo de salida basado en la conexion // que tiene el objeto objetoCliente. OutputStream salida = objetoCliente.getOutputStream(); DataOutputStream carritoSalida = new DataOutputStream(salida); Enciclopedia Conociendo Curso de Jsp y Servlets
130
carritoSalida.writeUTF("Yo me llamo cumbia yo soy la reina..."); System.out.println("Le envie al servidor la cancion YO ME LLAMO CUMBIA"); } catch(Exception e){ System.out.println("Errores en el cliente"); } } // Cierra public Servidor() public static void main(String[] args) { System.out.println("Hola Soy el CLIENTE"); Cliente principal = new Cliente(); } }
9.5.
El programa del cliente anterior lo queremos mejorar usando una interfaz de usuario mas agradable, el objetivo es mostrar una interfaz similar a la siguiente:
Para ello mejoramos el programa con las instrucciones siguientes: import java.net.*; // Para las conexiones import java.io.*; // Para flujos y archivos import java.awt.*; // Para botones, cajas, etc. public class Cliente extends Frame{ Panel panelcillo = new Panel(); TextField cajilla = new TextField(" Enciclopedia Conociendo "); Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva Button botoncillo = new Button("Enviar"); public Cliente(){ add(panelcillo); panelcillo.add(cajilla); panelcillo.add(botoncillo); try{ Socket objetoCliente = new Socket("localhost",85); System.out.println("Pude crear el objeto cliente");
131
// Esto crea un flujo de salida basado en la conexion // que tiene el objeto objetoCliente. OutputStream salida = objetoCliente.getOutputStream(); DataOutputStream carritoSalida = new DataOutputStream(salida); carritoSalida.writeUTF("Yo me llamo cumbia yo soy la reina..."); System.out.println("Le envie al servidor la cancion YO ME LLAMO CUMBIA"); } catch(Exception e){ System.out.println("Errores en el cliente"); } } // Cierra public Servidor() public static void main(String[] args) { System.out.println("Hola Soy el CLIENTE"); Cliente principal = new Cliente(); principal.setSize(800,600); principal.setVisible(true); } } Si, ya sabemos, el boton no ejecuta accin alguna. Para crear eventos en java se requiere usar un paquete que maneje eventos. Este paquete es el paquete Java.awt.event.*; El programa cliente mejora es el siguiente: import java.net.*; // Para las conexiones import java.io.*; // Para flujos y archivos import java.awt.*; // Para botones, cajas, etc. import java.awt.event.*; // Este paquete me permite manejar eventos. public class Cliente extends Frame{ Panel panelcillo = new Panel(); TextField cajilla = new TextField(" "); Button botoncillo = new Button("Enviar");
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva EventoEnviar objetoEvento = new EventoEnviar(); // Las clases en java que implementan ActionListener son // clases de tipo evento. Cuando se activa el evento // se ejecuta el metodo actionPerformed. public class EventoEnviar implements ActionListener{ public void actionPerformed(ActionEvent ev){ try{ Socket objetoCliente = new Socket("localhost",85); System.out.println("Pude crear el objeto cliente");
132
// Esto crea un flujo de salida basado en la conexion // que tiene el objeto objetoCliente. OutputStream salida = objetoCliente.getOutputStream(); DataOutputStream carritoSalida = new DataOutputStream(salida); carritoSalida.writeUTF(cajilla.getText()); System.out.println("Le envie al servidor la cancion YO ME LLAMO CUMBIA"); } catch(Exception e){ System.out.println("Errores en el cliente"); } } // Cierra public void actionPerformed } // Cierra ActionListener public Cliente(){ add(panelcillo); panelcillo.add(cajilla); panelcillo.add(botoncillo); // Esta instruccion asigna el evento al botoncillo // Osea cuando se pica sobre el boton se ejecuta el // metodo actionPerformed del objeto objetoEvento // que es de tipo EventoEnviar. botoncillo.addActionListener(objetoEvento);
} // Cierra public Servidor() public static void main(String[] args) { System.out.println("Hola Soy el CLIENTE"); Cliente principal = new Cliente(); principal.setSize(800,600); principal.setVisible(true); } }
Enciclopedia Conociendo
133
9.6. EL SERVIDOR CREA AADE A LA LISTA CADA VEZ QUE LLEGA UN CLIENTE
Para lograr que el servidor acepte varios clientes, lo primero que debe hacer el servidor es tener una lista simplemente enlazada en la que coloque las referencias de los clientes que se han conectado al servidor. Esto se logra por medio de una clase nueva llamada LISTACLIENTES, la cual contiene una subclase llamada NODOCLIENTE, la cual contendra la informacin necesaria de un solo cliente.
NULL
apCabeza
NODOCLIENTE
NULL
NODOCLIENTE
NODOCLIENTE
NULL
La anterior diagramacin es bastante compleja de implementar sin otro apuntador, con lo cual la situacin mas facil de implementar es de la siguiente manera: apCabeza NULL apFINAL Enciclopedia Conociendo Curso de Jsp y Servlets
134
NODOCLIENTE sig
NULL
NODOCLIENTE
NODOCLIENTE
NULL
apCabeza
apFinal
NODOCLIENTE
NODOCLIENTE
NODOCLIENTE
NULL
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva import java.net.ServerSocket; import java.net.Socket; public class SERVIDOR { LISTACLIENTES objListaClientes; public SERVIDOR(){ objListaClientes = new LISTACLIENTES(); try{ ServerSocket objServidor = new ServerSocket(85); while(true){ System.out.println("Esperando a un cliente"); Socket refClientecillo = objServidor.accept(); System.out.println("Ya llego este cliente"); objListaClientes.adicionarCliente(refClientecillo); objListaClientes.devolverListaClientes(); } // Cierra while } catch(Exception e){ System.out.println("Algo raro ocurrre en el servidor"); } } public static void main(String[] args) { // TODO, add your application code System.out.println("Hello World!"); SERVIDOR principal = new SERVIDOR(); } } Archivo LISTACLIENTES.java import java.net.Socket; public class LISTACLIENTES{ public class NODOCLIENTE{ Socket RefCliente = null; NODOCLIENTE sig; String val = ""; public NODOCLIENTE(){ sig = null; }// Cierra constructor NODOCLIENTE } // Cierra public class NodoCliente NODOCLIENTE apCabeza; NODOCLIENTE apFinal; public LISTACLIENTES(){ apCabeza = null; apFinal = null; } // Cierra public LISTACLIENTES()
135
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva public void adicionarCliente(Socket ref){ System.out.println("Estamos en la funcion adicionarCliente"); // Entramos a este if solo cuando // llega el primer cliente. if(apCabeza==null){ apCabeza = new NODOCLIENTE(); apCabeza.RefCliente = ref; // Recordemos que este es unico caso en el que ambos apuntadores // estan en el mismo NODOCLIENTE. apFinal = apCabeza; } // Cierra if(apCabeza==NULL) else{ NODOCLIENTE nuevoCliente = new NODOCLIENTE(); nuevoCliente.RefCliente = ref; apFinal.sig = nuevoCliente; // Verde apFinal = nuevoCliente; // Rojo } } // Cierra public adicionarCliente public void devolverListaClientes(){ System.out.println("Estamos en la funcion devolverListaClientes"); NODOCLIENTE apRecorrer; apRecorrer = apCabeza; // Recorre la lista de clientes. while(apRecorrer!=null){ System.out.println(apRecorrer.RefCliente.toString()); // Si no se ejecuta esto, se queda // en un ciclo infinito. apRecorrer = apRecorrer.sig; } // Cierra while } // Cierra public void devolverListaClientes() } // Cierra public class LISTACLIENTES El codigo del cliente es similar al siguiente: import java.net.Socket; public class CLIENTE { public CLIENTE(){ try{ Socket cliente = new Socket("localhost",85); } catch(Exception e){ System.out.println("Errores con el cliente"); } } // Cierra public CLIENTE() public static void main(String[] args) { // TODO, add your application code System.out.println("Hello World!"); Enciclopedia Conociendo
136
137
Hasta ahora cada vez que un cliente se conecta, en el lado del servidor se aade un nodo a la lista, el cual se encarga de atender a dicho cliente. Viene la parte mas dura que es lo que el servidor recibio del cliente, debe enviarlo a todos los clientes. lo mejor que se puede sin usar hilos es lo siguiente: import java.net.ServerSocket; import java.net.Socket; public class SERVIDOR { LISTACLIENTES objListaClientes; public SERVIDOR(){ objListaClientes = new LISTACLIENTES(); try{ ServerSocket objServidor = new ServerSocket(85); while(true){ System.out.println("Esperando a un cliente"); Socket refClientecillo = objServidor.accept(); System.out.println("Ya llego este cliente"); objListaClientes.adicionarCliente(refClientecillo); objListaClientes.devolverListaClientes(); } // Cierra while } catch(Exception e){ System.out.println("Algo raro ocurrre en el servidor"); } } public static void main(String[] args) { // TODO, add your application code System.out.println("Hello World!"); SERVIDOR principal = new SERVIDOR(); } }
Enciclopedia Conociendo
138
public SERVIDOR(){ objListaClientes = new LISTACLIENTES(); try{ ServerSocket objServidor = new ServerSocket(85); while(true){ System.out.println("Esperando a un cliente"); Socket refClientecillo = objServidor.accept(); System.out.println("Ya llego este cliente"); objListaClientes.adicionarCliente(refClientecillo); objListaClientes.devolverListaClientes(); } // Cierra while } catch(Exception e){ System.out.println("Algo raro ocurrre en el servidor"); } } public static void main(String[] args) { // TODO, add your application code System.out.println("Hello World!"); SERVIDOR principal = new SERVIDOR(); } } import java.net.Socket; import java.io.*; public class LISTACLIENTES{ public class SubProceso extends Thread{ String lectura; InputStream entrada; DataInputStream entra; public SubProceso(Socket r){ Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva try{ entrada = r.getInputStream(); entra = new DataInputStream(entrada); } catch(Exception e){ System.out.println("Error creadno el subproceso"); } } // Esto cierra el constructor SubProceso(Socket r) public void run(){ try{ while(true){ lectura = entra.readUTF(); System.out.println("El cliente envio "+lectura); enviarAClientes(lectura); } // Cierra while } catch(Exception e){ System.out.println("Errores corriendo hilo"); } // Cierra catch } // Cierra run() } // Cierra class SubProceso public class NODOCLIENTE{ Socket RefCliente = null; NODOCLIENTE sig; String val = ""; public NODOCLIENTE(){ sig = null; }// Cierra constructor NODOCLIENTE } // Cierra public class NodoCliente NODOCLIENTE apCabeza; NODOCLIENTE apFinal; public LISTACLIENTES(){ apCabeza = null; apFinal = null; } // Cierra public LISTACLIENTES() public void adicionarCliente(Socket ref){ System.out.println("Estamos en la funcion adicionarCliente"); // Entramos a este if solo cuando // llega el primer cliente. if(apCabeza==null){ apCabeza = new NODOCLIENTE(); apCabeza.RefCliente = ref; // Recordemos que este es unico caso en el que ambos apuntadores // estan en el mismo NODOCLIENTE. apFinal = apCabeza; try{ SubProceso nuevosubproceso = new SubProceso(ref); Enciclopedia Conociendo
139
Autor: Luis Felipe Wanumen Silva nuevosubproceso.start(); } // Cierra try catch(Exception e){ System.out.println("Error leyendo datos del cliente"); } } // Cierra if(apCabeza==NULL) else{ NODOCLIENTE nuevoCliente = new NODOCLIENTE(); // RefCliente es el que realmente atiende al cliente. nuevoCliente.RefCliente = ref; try{ SubProceso nuevosubproceso = new SubProceso(ref); nuevosubproceso.start(); } // Cierra try catch(Exception e){ System.out.println("Error leyendo datos del cliente"); } apFinal.sig = nuevoCliente; // Verde apFinal = nuevoCliente; // Rojo } } // Cierra public adicionarCliente public void devolverListaClientes(){ System.out.println("Estamos en la funcion devolverListaClientes"); NODOCLIENTE apRecorrer; apRecorrer = apCabeza; // Recorre la lista de clientes. while(apRecorrer!=null){ System.out.println(apRecorrer.RefCliente.toString()); // Si no se ejecuta esto, se queda // en un ciclo infinito. apRecorrer = apRecorrer.sig; } // Cierra while } // Cierra public void devolverListaClientes()
140
public void enviarAClientes(String mensaje){ System.out.println("Estamos en la funcion devolverListaClientes"); NODOCLIENTE apRecorrer; apRecorrer = apCabeza; // Recorre la lista de clientes. while(apRecorrer!=null){ try{ OutputStream salida = apRecorrer.RefCliente.getOutputStream(); DataOutputStream sale = new DataOutputStream(salida); sale.writeUTF(mensaje); } catch(Exception e){ System.out.println("Error enviando a todos los clientes"); } // Si no se ejecuta esto, se queda // en un ciclo infinito. Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva apRecorrer = apRecorrer.sig; } // Cierra while } // Cierra public void enviarAClientes() } // Cierra public class LISTACLIENTES El lado del cliente seria: import java.net.Socket; import java.io.*; import java.awt.event.*; // Botones, Labels, Check, Group, TextAreas, paneles import java.awt.*; public class CLIENTE extends Frame{ OutputStream salida; DataOutputStream carritoSalida; /* InputStream entrada; DataInputStream carritoEntrada; */ Socket cliente; Panel panel1 = new Panel(); Panel panel2 = new Panel(); TextField texto = new TextField(30); TextArea ta = new TextArea(); Button b1 = new Button("Enviar"); BorderLayout border = new BorderLayout(0,0); Evento objetoEvento = new Evento(); SubProceso objSubproceso; public class Evento implements ActionListener{ public void actionPerformed(ActionEvent ev){ System.out.println("Me ponchaste"); try{ carritoSalida.writeUTF(texto.getText()); } catch(Exception e){ System.out.println("Error escribiendo en la caja de texto"); } } } // Cierra public class Evento Enciclopedia Conociendo
141
142
public class SubProceso extends Thread{ InputStream entradilla; DataInputStream entradilla1; public SubProceso(Socket r){ try{ entradilla = r.getInputStream(); entradilla1 = new DataInputStream(entradilla); } catch(Exception e){ System.out.println("Error en Constructor"); } } public void run(){ while(true){ try{ String lectura = entradilla1.readUTF(); System.out.println("El mensaje del servidor es "+lectura); String textillos = ""; textillos = ta.getText(); textillos = textillos + lectura + "\n"; ta.setText(textillos); } catch(Exception e){ System.out.println("Error leyendo datos del servidor"); } } } // Cierra run } // Cierra public class SubProceso public CLIENTE(){ setLayout(border); panel1.setBackground(Color.blue); panel2.setBackground(Color.yellow); add("Center", panel1); panel1.add(ta); add("North", panel2); panel2.add(texto); panel2.add(b1); b1.addActionListener(objetoEvento); this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); try{ Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva cliente = new Socket("localhost",85); // Estas tres lineas son para que el cliente envie // el texto "Yo soy un cliente" salida = cliente.getOutputStream(); carritoSalida = new DataOutputStream(salida); InputStream entrada = cliente.getInputStream(); DataInputStream carritoEntrada = new DataInputStream(entrada); objSubproceso = new SubProceso(cliente); objSubproceso.start(); } // Cierra try catch(Exception e){ System.out.println("Errores con el cliente"); } } // Cierra public CLIENTE() public static void main(String[] args) { // TODO, add your application code System.out.println("Hello World!"); CLIENTE principal = new CLIENTE(); principal.setSize(400,300); principal.setVisible(true); } }
143
Enciclopedia Conociendo
144
10.1.1. DESCRIPCION
El ejemplo que se muestra a continuacin realmente solamente implementa en un solo sentido el flujo de informacin, es decir los clientes se conectan e intentan enviar flujos de informacin a los servidores, y los servidores solamente reciben la informacin y la manipulan. La otra parte en donde el servidor enva informacin al cliente no se ha tenido en cuenta.
Enciclopedia Conociendo
145
inicio
ServerSocket_ leyendoDatos()
ServerSocket_esperandoFl ujodeDatos
ServerSocket_acepta ndoConeccionCliente
El servidor debe iniciar primero la aplicacin de lo contrario los clientes no y en este caso particular aparecer en el lado del cliente un mensaje similar al siguiente: El diagrama de estados anterior muestra que no es posible que un socketservidor pase a ser un socket que esta en estado de estar aceptando conecciones si primero no ha estado esperando la coneccion de un cliente. Tambien muestra que no es posible que un socket pasa el estado de estar esperando a un cliente si previamente no ha estado en Iniciado. El estado recursivo es presenta cuando se estan enviando datos, caso en el cual no hay que volver al estado de iniciado ni ninguno de los anterior, sino que se puede seguir en dicho estado a menos que se caiga la coneccion y se pasaria al estado de desactivado. Mi nuevo estado es denegado
Enciclopedia Conociendo
146
Pero bueno, teniendo en cuenta el caso perfecto en el cual se inicia primero el servidor, tenemos que el primer cliente que se conecte sera atendido por medio del metodo accept() del servidor. Esta funcion permite que el estado del cliente pase a ser conectado. La aplicacin servidora es: Archivo MyApp.java import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); Servidor servidor = new Servidor(); servidor.iniciado(); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } } Archivo Servidor.java import java.net.ServerSocket; import java.net.Socket; import java.io.*; public class Servidor{ ServerSocket objServidor; public Servidor(){ iniciado(); } public void iniciado(){ try{ objServidor = new ServerSocket(4000); System.out.println("Se pudo crear el objeto Servidor"); esperando(); Socket refCliente1 = objServidor.accept(); System.out.println("Ha llegado un cliente y yo como servidor lo he aceptado"); aceptandoConeccionCliente(); InputStream entrada; Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva entrada = refCliente1.getInputStream(); esperandoFlujodeDatos(); DataInputStream entra = new DataInputStream(entrada); String lectura; while(true){ lectura = entra.readUTF(); leyendoDatos(); analizandoDatosQueLLegaron(); System.out.println(lectura); } } catch(Exception e){ System.out.println("No se pudo crear el objeto Servidor"); socketFueraContexto(); } // Cierar catch } // Cierra public void iniciado() public void socketFueraContexto(){ System.out.println("Estoy fuera de contexto"); } // Cierra void socketFueraContexto public void esperando(){ System.out.println("Estoy esperando a un cliente"); } // Cierra public void esperando() public void esperandoFlujodeDatos(){ System.out.println("esperandoFlujodeDatos"); } public void analizandoDatosQueLLegaron(){ System.out.println("Estoy analizando Datos Que LLegaron"); } // Cierra analizandoDatosQueLLegaron() public void leyendoDatos(){ System.out.println("Estoy leyendo Datos"); } public void aceptandoConeccionCliente(){ System.out.println("Estoy aceptandoConeccionCliente"); } // Cierra public void esperando() } // Cierra public class Servidor
147
Enciclopedia Conociendo
148
SocketClien te_aceptado
SocketCliente_ enviandoDatos
SocketCliente_esperandoC onfirmacionRecibidoServidor
SocketCliente_env iandoFlujodeDatos
La aplicacin del lado del cliente esta compuesta por dos archivos MyApp.java y Cliente.java Archivo MyApp.java import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { TextField texto = new TextField(" "); Cliente cliente = new Cliente(); // Evento objEvento = new Evento(); Button boton1 = new Button("Enviar"); Panel panel1 = new Panel();
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); cliente.conectar(); cliente.setVentana(this); add(panel1); panel1.add(texto); panel1.add(boton1); // add(texto); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.setVisible(true); } } Archivo Cliente.java import java.net.Socket; import java.io.*; import java.awt.event.*; public class Cliente{ Socket objCliente; DataOutputStream sale; OutputStream salida; String escritura = "";; MyApp refVenta = null; EventoEnviar objEnvio = new EventoEnviar(); public void setVentana(MyApp ob){ refVenta = ob; refVenta.boton1.addActionListener(objEnvio); } // Cierra public void setVentana() public class EventoEnviar implements ActionListener{ public void actionPerformed(ActionEvent ev){ try{ escritura = refVenta.texto.getText(); sale.writeUTF(escritura); Enciclopedia Conociendo
149
Autor: Luis Felipe Wanumen Silva System.out.println("Ya se envio "+escritura); } catch(Exception e){ } } } // Cierra class EventoEnviar public Cliente(){ objCliente = null; } // Cierra public Cliente() public void conectar(){ try{ objCliente = new Socket("orion",4000); aceptado(); salida = objCliente.getOutputStream(); enviandoFlujodeDatos(); sale = new DataOutputStream(salida); escritura = "Yo soy el mejor cliente"; enviandoDatos(); sale.writeUTF(escritura); esperandoConfirmacionRecibidoServidor(); System.out.println("Ya envie una parte"); } catch(Exception e){ denegado(); } } // Cierra public void conectar() public void esperandoConfirmacionRecibidoServidor(){ System.out.println("Estoy esperando Confirmacion de Recibido del Servidor"); } // Cierra esperandoConfirmacionRecibidoServidor public void enviandoDatos(){ System.out.println("Envando datos"); } // Cierra public void enviandoDatos() public void enviandoFlujodeDatos(){ System.out.println("Estoy empaquetando Flujo de Datos a enviar"); } public void aceptado(){ System.out.println("Mi nuevo estado es aceptado"); } // Cierra public void aceptado() public void denegado(){ System.out.println("Mi nuevo estado es denegado"); } // Cierra public void denegado() } // CIerra public class Cliente
150
Enciclopedia Conociendo
151
El primer estado es un estado desactivo el del sobket que envia, debido a que no se ha creado. Pero tan pronto se crea el socket, el programa observa si se ha recibido aceptacin por parte del servidor y en este caso pasa al estado de aceptado. Despus de estar en el estado de aceptado el cliente intenta construir un flujo de datos que envuelve en un objeto envoltorio para ser enviado al servidor y pasa inmediatamente al estado de enviandoFlujoDeDatos. Una vez se ha estado en este estado y se ha logrado satisfactoriamente la creacin de dicho flujo se procede a estar en el estado de enviandoDatos y entonces solamente se puede pasar al estado de enviandoDatos o al estado de desactivo si algo anomalo ocurre. Observese la continuidad del estado enviandoDatos, este estado no permite devolverse hacia estados predecesores y el unico estado que puede ocurrir despus de este es el mismo o en su defecto y por error en las comunicaciones el estado de desactivo.
Enciclopedia Conociendo
152
MyApp grilla : GridLayout = new borde : BorderLayout = new paneles : panel[][] = new gp : Graphics = new actual_x : int = null actual_y : int = null superior : Panel = new arriba : Panel = new inferior : Panel = new ta : TextArea = new t1 : TextField = new IngSistemas : pirata = new Rampa : rampa = new Mar : mar = new salvado : boolean = false Barco : barco = new Muelle : muelle = new paint(Graphics) : void init() : void keyDown(Event, int) : boolean muelle peso_actual : int = 70 peso_cadena : String = "" informar_peso: void()
rampa pos_x : int = 0 pos_y : int = 0 mensaje : String = "El Muelle Habla" validar_salida(int, int) : void informar_caer_al_mar: void()
Enciclopedia Conociendo
153
import java.awt.*; import java.awt.event.*; import java.applet.*; public class MyApp extends Applet { GridLayout grilla = new GridLayout(15,5,1,1); BorderLayout borde = new BorderLayout(4,4); Panel paneles[][] = new Panel[5][15]; Graphics gp[][] = new Graphics[5][15]; int actual_x, actual_y; Panel superior = new Panel(); Panel arriba = new Panel(); Panel inferior = new Panel(); TextArea ta = new TextArea(5,30); TextField t1 = new TextField("EL PIRATA PESA"); pirata IngSistemas = new pirata(); rampa Rampa = new rampa(); mar Mar = new mar(); boolean salvado = false; barco Barco = new barco(); muelle Muelle = new muelle(); public void paint(Graphics g) { for(int x = 0; x<5; x++){ for(int y = 0; y<15; y++){ gp[x][y] = paneles[x][y].getGraphics(); if(x == actual_x && y == actual_y){ paneles[x][y].setBackground(Color.red); } else{ paneles[x][y].setBackground(Color.white); } // Cierra else } // cierra for interno } // cierra for externo } // cierra paint() public class mar{
Enciclopedia Conociendo
154
public void ahogar(pirata hombre){ String cadena = ta.getText().trim(); cadena = cadena + "\n EL MAR HABLA: \n"; cadena = cadena + "ESTOY AHOGANDO AL MUERTO"; ta.setText(cadena); IngSistemas.dejarse_ahogar(); } } // Cierra class mar public void init(){ actual_x = 2; actual_y = 0; setLayout(borde); superior.setLayout(new BorderLayout(4,5)); superior.add("Center", arriba); add("Center", superior); add("South", inferior); inferior.add(ta); inferior.add(t1); arriba.setLayout(grilla); setBackground(Color.black); for(int x = 0; x<5; x++){ for(int y = 0; y<15; y++){ paneles[x][y] = new Panel(); } } for(int y = 0; y<15; y++){ for(int x = 0; x<5; x++){ arriba.add(paneles[x][y]); } } Muelle.soportar_peso(IngSistemas.peso); Muelle.informar_peso(); } // Cierra funcion init() public class barco{ String mensaje = ""; public void salvar_pirata(){ salvado = true; mensaje = ta.getText().trim(); mensaje = mensaje + "\n EL BARCO HABLA \n"; mensaje = mensaje + "SALVADO EL PIRATA"; ta.setText(mensaje); } } // Cierra class barco
Enciclopedia Conociendo
155
public class muelle{ int peso_actual = 70; String peso_cadena = ""; public void soportar_peso(int valor){ peso_actual = valor; } // Cierra void soportar_peso public void informar_peso(){ peso_cadena = t1.getText().trim(); peso_cadena = peso_cadena + " "; peso_cadena = peso_cadena + peso_actual; peso_cadena = peso_cadena + "KILOS "; t1.setText(peso_cadena); }// int informar_peso } // Cierra class muelle public class rampa{ int pos_x=0; int pos_y=0; String mensaje = "EL MUELLE HABLA; \n"; public void validar_salida(int x, int y){ pos_x = x; pos_y = y; if(pos_y<0){ mensaje = mensaje + "Fuera ta.setText(mensaje); tirar_al_mar(); } if(pos_x<0){ mensaje = mensaje + "Fuera ta.setText(mensaje); tirar_al_mar(); } if(pos_x>=5){ mensaje = mensaje + "Fuera ta.setText(mensaje); tirar_al_mar(); } if(pos_y>=15){ mensaje = mensaje + "NO LO ta.setText(mensaje); Barco.salvar_pirata(); } del rango y";
DEJE CAER";
Enciclopedia Conociendo
156
} // Cierra void validar_salida() public void tirar_al_mar(){ Mar.ahogar(IngSistemas); } // Cierra void tirar_al_mar() } // Cierra class rampa public class pirata{ int pos_x; int pos_y; int peso = 75; // Kilos boolean estado_vida = true; public void moverse(int i, int j){ if(estado_vida){ pos_x = i; pos_y = j; Rampa.validar_salida(pos_x, pos_y); } // Cierra if } // Cierra moverse public void dejarse_ahogar(){ estado_vida = false; } //Cierra void dejarse_ahogar } // Cierra clase pirata public boolean keyDown(Event evt, int key){ if(IngSistemas.estado_vida && salvado==false){ switch(key){ case Event.RIGHT: actual_x++; IngSistemas.moverse(actual_x, actual_y); repaint(); break; case Event.LEFT: actual_x--; IngSistemas.moverse(actual_x, actual_y); repaint(); break; case Event.UP: actual_y--; IngSistemas.moverse(actual_x, actual_y); repaint(); break;
Enciclopedia Conociendo
157
} return true; } // Cierra if externo return false; } // Cierra boolean // Cierra clase MyApp
Enciclopedia Conociendo
158
Ahora bien, el usuario, puede desplazarse mediante las teclas de direccin del teclado y de esta manera podr mover el pirata. (que en este caso es la posicin roja). Si el usuario no lo deja desbordarse por alguna posicin de la derecha o de la izquierda y llega a la posicin de debajo de la figura, se obtiene un resultado similar al siguiente:
Enciclopedia Conociendo
159
Pero si el usuario lo deja desbordarse por la derecha o por la izquierda, aparecer una pantalla similar a la siguiente:
Enciclopedia Conociendo
160
Con lo cual se indica que efectivamente se ha caido el pirata al mar y por supuesto se ha ahogado.
Enciclopedia Conociendo
161
avion h : Graphics = null x : int = 150 y : int = 400 cuerpo : rectangulo = new cola : rectangulo = new ala_superior : triangulo = new ala_inferior : triangulo = new punta : triangulo = new matriz : int[][] = new int[17][4] colita : int[][] = null cuerpito : int[][] = null puntica : int[][] = null alita_arriba : int[][] = null alita_abajo : int[][] = new trompita : int[][] = new alejarse() : void ascender() devolver_grafica() : int[][] moverse() avion()
rectangulo h : Graphics = null posx : int = null posy : int = null ancho : int = null alto : int = null rectangulillo : int[][] = new rectangulo() devolver_grafica: int[][]() posicion_derecha: int() posicion_superior: int() posicion_inferior: int() posicionar(rectangulo) : void actualizar_rectangulo(int int int int) : void alargar: void() adelgazar: void() triangulo posx : int = null posy : int = null posx1 : int = null posy1 : int = null posx2 : int = null posy2 : int = null pos : int[][] = new alto : int = null devolver_grafica: int[][]() ajustarse(String) : void ajustarse(String, rectangulo) : void triangulo()
canvitas gra : Graphics = null pintar : int = 0 puntos : int = null apariciones : int = 100 referencia_avion : avion = null pintar(avion) : void paint(Graphics) : void 1..1
Enciclopedia Conociendo
1..1
MyApp tablero : canvitas = new avioncito Curso de Jsp y Servlets : avion = new MyApp() main()
162
avion.java
import java.awt.*; import java.awt.event.*; import java.applet.*; public class avion{ Graphics h; int x = 150; int y = 400; rectangulo cuerpo = new rectangulo(); rectangulo cola = new rectangulo(); triangulo ala_superior = new triangulo(); triangulo ala_inferior = new triangulo(); triangulo punta = new triangulo(); int matriz[][] = new int[17][4]; int colita[][]; int cuerpito[][]; int puntica[][];
Enciclopedia Conociendo
163
int alita_arriba[][]; int alita_abajo[][] = new int[3][4]; int trompta[][] = new int[3][4]; public avion(){ // Por medio de punta se establece // el tamao del avion punta.alto = 40; }// Cierra public avion public void alejarse(){ if(punta.alto>10){ punta.alto = punta.alto - 1; }// Cierra ir } // Cierra void alejarse public void ascender(){ if(y>20){ y = y - 5; }// Cierra ir } // Cierra void alejarse public int[][] devolver_grafica(){ // punta.alto = 20; punta.posx = x; punta.posy = y; punta.ajustarse("punta"); cuerpo.alto = punta.alto; cuerpo.ancho = cuerpo.alto*6; cuerpo.posx = punta.posx1-cuerpo.ancho; cuerpo.posy = punta.posy - (int)punta.alto/2; cola.posicionar(cuerpo); ala_superior.ajustarse("ala_superior", cuerpo); ala_inferior.ajustarse("ala_inferior", cuerpo); colita = cola.devolver_grafica(); puntica = punta.devolver_grafica(); cuerpito = cuerpo.devolver_grafica(); alita_arriba = ala_superior.devolver_grafica(); alita_abajo = ala_inferior.devolver_grafica(); for(int i = 0; i<4; i++){ for(int j = 0; j<4; j++){
Enciclopedia Conociendo
164
matriz[i][j] = colita[i][j]; } // Cierra for interno for(int k = 0; k<4; k++){ matriz[i+4][k] = cuerpito[i][k]; } // Cierra for interno for(int m = 0; m<3; m++){ matriz[m+8][i] = puntica[m][i]; } // Cierra for interno for(int n = 0; n<3; n++){ matriz[n+11][i] = alita_arriba[n][i]; } // Cierra for interno for(int p = 0; p<3; p++){ matriz[p+14][i] = alita_abajo[p][i]; } // Cierra for interno } // Cierra for externo return matriz; } // Cierra devolver_grafica public void moverse(){ x = x+8; }// Cierra void moverse } // Cierra class avion
Enciclopedia Conociendo
165
canvitas.java import java.awt.*; import java.awt.event.*; import java.applet.*; public class canvitas extends Canvas{ Graphics gra; int pintar = 0; int puntos[][]; int apariciones = 100; avion referencia_avion; public void pintar(avion obj_volador){ puntos = obj_volador.devolver_grafica(); referencia_avion = obj_volador; repaint(); } // Cierra pintar public void paint(Graphics g){ this.gra = g; g.setColor(Color.blue); while(apariciones>0){ referencia_avion.moverse(); referencia_avion.alejarse(); referencia_avion.ascender(); puntos = referencia_avion.devolver_grafica(); g.setColor(Color.blue); for(int i = 0; i<17; i++){ g.drawLine(puntos[i][0], puntos[i][1], puntos[i][2], puntos[i][3]); } try{ Thread.sleep(40); } catch(InterruptedException e){ } // Cierra catch g.setColor(Color.yellow); for(int i = 0; i<17; i++){ g.drawLine(puntos[i][0], puntos[i][1], puntos[i][2], puntos[i][3]); } setBackground(Color.yellow); g.drawString("ESTO ES EL CANVAS", 200,300); apariciones--; } // Cierra while } // Cierra public void paint } // Cierra class canvitas
Enciclopedia Conociendo
166
MyApp.java import java.awt.*; import java.awt.event.*; public class MyApp extends Frame { canvitas tablero = new canvitas(); avion avioncito = new avion(); int apariciones = 500; public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); add(tablero); tablero.pintar(avioncito); } public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(960,600); f.show(); } }
rectangulo.java
import java.awt.*; import java.applet.*; public class rectangulo{ Graphics h; int posx, posy, ancho, alto; int rectangulillo[][] = new int[4][4]; public rectangulo(){
Enciclopedia Conociendo
167
} // Cierra public rectangulo public int[][] devolver_grafica(){ rectangulillo[0][0] = posx; rectangulillo[0][1] = posy; rectangulillo[0][2] = posx+ancho; rectangulillo[0][3] = posy; rectangulillo[1][0] rectangulillo[1][1] rectangulillo[1][2] rectangulillo[1][3] rectangulillo[2][0] rectangulillo[2][1] rectangulillo[2][2] rectangulillo[2][3] = = = = = = = = posx; posy; posx; posy+alto; posx+ancho; posy; posx+ancho; posy+alto;
rectangulillo[3][0] = posx; rectangulillo[3][1] = posy+alto; rectangulillo[3][2] = posx+ancho; rectangulillo[3][3] = posy+alto; return rectangulillo; } // Cierra int[][] devolver_grafica public int posicion_derecha(){ return posx+ ancho; } // Cierra int posicion_derecha public int posicion_superior(){ return posy; } // Cierra int posicion_superior public int posicion_inferior(){ return posy+alto; } // Cierra int posicion_inferior public void posicionar(rectangulo rect){ ancho = (int)rect.ancho/5; alto = rect.alto*3; posx = rect.posx -ancho; posy = rect.posy - (rect.alto); } // Cierra mover_derecha
Enciclopedia Conociendo
168
public void actualizar_rectangulo(int x, int y, int ancho, int alto){ posx = x; posy = y; this.ancho = ancho; this.alto = alto; } // Cierra public rectangulo public void alargar(int valor){ ancho = ancho + valor; } // Cierra alargar public void adelgazar(int valor){ alto = alto - valor; } // Cierra adelgargar } // Cierra class rectangulo
triangulo.java
import java.applet.*; public class triangulo{ int posx; int posy; int posx1; int posy1; int posx2; int posy2; int pos[][] = new int[3][4]; int alto; public int[][] devolver_grafica(){
Enciclopedia Conociendo
169
pos[0][0] pos[0][1] pos[0][2] pos[0][3] pos[1][0] pos[1][1] pos[1][2] pos[1][3] pos[2][0] pos[2][1] pos[2][2] pos[2][3]
= = = = = = = = = = = =
posx; posy; posx1; posy1; posx; posy; posx2; posy2; posx1; posy1; posx2; posy2;
public void ajustarse(String tipo){ if(tipo.equals("punta")){ posx1 = posx - (int)alto; posy1 = posy - (int)alto/2; posx2 = posx - (int)alto; posy2 = posy + (int)alto/2; System.out.println("posx = "+ posx ); System.out.println("posy = "+ posy ); System.out.println("posx1 = "+ posx1 ); System.out.println("posy1 = "+ posy1 ); System.out.println("posx2 = "+ posx2 ); System.out.println("posy2 = "+ posy2 ); } }// Cierra if tipo == "punta" public void ajustarse(String tipo, rectangulo body){ if(tipo.equals("ala_superior")){ posy = body.posy - body.alto*2; posx = body.posx + (int )body.ancho/3; posx1 = body.posx + (int)body.ancho/3 + (int)body.ancho/6; posy1 = body.posy; posx2 = body.posx + (int)body.ancho/3 + (int)body.ancho/3; posy2 = body.posy; }// Cierra if tipo == "ala_superior" if(tipo.equals("ala_inferior")){
Enciclopedia Conociendo
170
posy = body.posy + body.alto + body.alto*2; posx = body.posx + (int )body.ancho/3; posx1 = body.posx + (int)body.ancho/3 + (int)body.ancho/6; posy1 = body.posy + body.alto; posx2 = body.posx + (int)body.ancho/3 + (int)body.ancho/3; posy2 = body.posy + body.alto; System.out.println("ESTOY EN EL FI"); System.out.println("posx = "+ posx); System.out.println("posy = "+ posy); System.out.println("posx1 = "+ posx1); System.out.println("posy1 = "+ posy1); System.out.println("posx2 = "+ posx2); System.out.println("posy2 = "+ posy2); }// Cierra if tipo == "ala_superior" } // Cierra void ajustarse public triangulo(){ } // Cierra triangulo } // Cierra class triangulo
Enciclopedia Conociendo
171
Y a medida que pasa el tiempo se va elevando el avin, tal como se muestra en la siguiente grfica:
Enciclopedia Conociendo
172
Finalmente el avin llega a un punto en el que alcanza la altura mxima y contina volando.
Enciclopedia Conociendo
173
public class MyApp extends Frame { public MyApp(){ this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } public static String host String from String to = void main (String args[]) throws Exception { = "fenix.udistrital.edu.co"; = "lwanumen@udistrital.edu.co"; "lwanumen@udistrital.edu.co";
// Obtiene propiedades del sistema Properties props = System.getProperties(); // Configura servidor de correo props.put("mail.smtp.host", host); // Consigue la sesion Session session = Session.getDefaultInstance(props, null); // Define el mensaje MimeMessage message = new MimeMessage(session); // Relaciona mensaje con direccion email remitente Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva message.setFrom(new InternetAddress(from)); // Relaciona mensaje con direccion email destinataria message.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); // Establece el destinatario message.setSubject("Este es el texto del asunto"); // Establece contenido del mensaje message.setText("HOLA PROFESOR WANUMEN"); // Envia el mensaje Transport.send(message); }
174
El anterior ejemplo no funciona desde cualquier servidor de internet ubicado en cualquier direccin de internet. Fijmonos que no requiere la contrasea o clave del correo electrnico para enviar correo.
public class MyApp { public static void main(String[] args) { String to = "lwanumen@udistrital.edu.co"; String from = "lwanumen@udistrital.edu.co"; String host = "fenix.udistrital.edu.co"; String filename = "hola.txt"; boolean debug = true; String msgText1 = "Envio de archivos.\n"; String subject = "enviando un file"; // Crea algunas propiedades y consigue los valores // por defecto de la Sesin Properties props = System.getProperties(); props.put("mail.smtp.host", host); Session session = Session.getInstance(props, null); session.setDebug(debug); try { Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva // crea un mensaje MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress(from)); InternetAddress[] address = {new InternetAddress(to)}; msg.setRecipients(Message.RecipientType.TO, address); msg.setSubject(subject); // crea y asigna la primera parte del mensaje MimeBodyPart mbp1 = new MimeBodyPart(); mbp1.setText(msgText1); // crea la segunda parte del mensaje MimeBodyPart mbp2 = new MimeBodyPart(); // adjunta el archive al mensaje mbp2.attachFile(filename); // crea un Multipart y adiciona las partes aqui. Multipart mp = new MimeMultipart(); mp.addBodyPart(mbp1); mp.addBodyPart(mbp2); // adiciona el Multipart al mensaje msg.setContent(mp); // asigna la fecha al encabezado msg.setSentDate(new Date()); /* * Si usted desea controlar el Content-Transfer-Encoding * del archive adjunto, ejecute las 2 lneas. Normalmente * usted nunca necesitara hacer esto. * msg.saveChanges(); mbp2.setHeader("Content-Transfer-Encoding", "base64"); */ // envia el mensaje Transport.send(msg); } catch (MessagingException mex) { mex.printStackTrace(); Exception ex = null; if ((ex = mex.getNextException()) != null) { ex.printStackTrace(); } } catch (IOException ioex) { ioex.printStackTrace(); } } }
175
Enciclopedia Conociendo
176
String lee = entra.readLine(); System.out.println(lee); } catch(Exception e){ System.out.println(e.toString()); } } public static void main(String[] args) { Main programa = new Main(); } }
177
BUILD SUCCESSFUL (total time: 0 seconds) Si el servicio no estuviera disponible el servidor habra respondido con el cdigo de error numero 421. Observemos que en el ejemplo anterior se crean dos canales: Uno para la entrada de datos y otro para la salida de datos llamados entrada y salida respectivamente. Con el canal de entrada se crea un buffer y con el canal de salida se crea un escritor, el bufer lee con la funcin readLine() y almacena en la variable leido, en tanto que el escritor referenciado con la variable sale no se ha implementado.
178
salida.println( "Mensaje de prueba "+timeStamp ); salida.println( "." ); System.out.println(entrada.readLine()); } catch(Exception e){ } } public static void main(String[] args) { Main programa = new Main(); } }
Es importante tener en cuenta que este ejercicio se puede modificar para que enve archivos adjuntos, y muchas otras cosas mas.
Enciclopedia Conociendo
179
public class MyApp { public static void main(String[] args) { String server ="gemini.udistrital.edu.co"; String user = "lwanumen"; String passwd ="1234"; FtpClient client =new FtpClient(); try { client.openServer(server); client.login(user, passwd); client.binary(); client.cd("LUCHIN"); } catch (IOException e) { e.printStackTrace(); } try { TelnetInputStream in = client.get("ftp1.txt"); FileOutputStream sale =new FileOutputStream("d:\\a.txt"); int t; int i; byte []h=new byte[100]; //while(t=in.read()) //System.out.println(in.); i=in.read(h); sale.write(h); //DataInputStream t=3Dnew h.toString(); Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva System.out.println("valor=3D"+h); } catch (IOException e) { e.printStackTrace(); } } // main } // Cierra FTP
180
Para ejecutar los ejemplos siguientes se puede descargar un jar llamado simpleftp.jar que se puede descargar de la siguiente direccin electrnica: http://www.jibble.org/files/simpleftp.jar
public class MyApp extends Frame { public MyApp() { this.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); try { SimpleFTP ftp = new SimpleFTP(); // Nos conectamos a servidor FTP por puerto 21 ftp.connect("ftp.udistrital.edu.co", 21, "lwanumen", "1234"); // Establecemos el modo binario ftp.bin(); // nos pasamos al directorio llamado "javaweb" // que se encuentra en el servidor FTP. ftp.cwd("javaweb");
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva // Subimos el archivo ftp.stor(new File("hojadevida.txt")); ftp.stor(new File("fotojojavida.png")); // Nos desconectamos del servidor FTP. ftp.disconnect(); } catch (IOException e) { } } // Cierra public MyApp public static void main(String args[]) { System.out.println("Starting App"); MyApp f = new MyApp(); f.setSize(100,100); f.show(); } }
181
public class MyApp{ private BufferedReader lector = null; private BufferedWriter escritor = null; Socket socket = null; public MyApp(){ try{ // CREAR EL CLIENTE socket = new Socket("gemini.udistrital.edu.co", 21); // CREAR EL FLUJO DE ENTRADA Y DE SALIDA lector = new BufferedReader(new Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva InputStreamReader(socket.getInputStream())); escritor = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // LEER DEL SERVIDOR String line = lector.readLine(); System.out.println(line); // // // if VERIFICAR LA RESPUESTA DEL SERVIDOR VERIFICAR QUE EL SERVIDOR ESTE ARRIBA Y PREPARADO PARA ACEPTAR USUARIOS (!line.startsWith("220 ")){ throw new IOException("recibido respuesta No conocida");
182
} else{ System.out.println("220 Servicio preparado nuevo usuario"); } // ENVIARLE EL NOMBRE DE USUARIO escritor.write("USER lwanumen\n"); escritor.flush(); // CAPTURAR LA RESPUESTA DEL SERVIDOR FRENTE A LA PETICION // DE NOMBRE DE USUARIO line = lector.readLine(); // VERIFICAR QUE LA RESPUESTA DEL SERVIDOR SEA CORRECTA // Y QUE HALLA DICHO QUE EL USUARIO EXISTE if (!line.startsWith("331 ")){ throw new IOException("El usuario no existe"); } else{ System.out.println("331 Usuario OK, necesita contrasea"); } // ENVIARLE EL PASSWORD DEL USUARIO escritor.write("PASS LUISLUIS\n"); escritor.flush(); // CAPTURAR LA RESPUESTA DEL SERVIDOR FRENTE A LA PETICION // DE ENVIO DEL PASSWORD line = lector.readLine(); // VERIFICAR QUE LA RESPUESTA DEL SERVIDOR SEA CORRECTA // Y QUE HALLA DICHO QUE EL PASSWORD ES CORRECTO if (!line.startsWith("230 ")){ throw new IOException("El password es incorrecto"); } else{ System.out.println("Usuario conectado, contine"); } // SOLICITAMOS AL SERVIDOR EL NOMBRE DEL DIRECTORIO Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva // DE TRABAJO escritor.write("PWD \n"); escritor.flush(); // CAPTURAR LA RESPUESTA DEL SERVIDOR FRENTE A LA PETICION // DE CONOCER EL NOMBRE DEL DIRECTORIO line = lector.readLine(); // // // if
183
VERIFICAR QUE LA RESPUESTA DEL SERVIDOR SEA CORRECTA Y QUE HALLA DICHO QUE SE PUDO ESTABLECER UN NOMBRE DE DIRECTORIO ACTUAL (line.startsWith("257 ")) { System.out.println("Ruta creada"); int firstQuote = line.indexOf('\"'); int secondQuote = line.indexOf('\"', firstQuote + 1); if (secondQuote > 0) { String dir = line.substring(firstQuote + 1, secondQuote); System.out.println("El directorio de trabajo es "+dir); }
// SOLICITAMOS AL SERVIDOR QUE CAMBIE AL DIRECTORIO // DE TRABAJO LUCHIN escritor.write("CWD LUCHIN\n"); escritor.flush(); // CAPTURAR LA RESPUESTA DEL SERVIDOR FRENTE A LA PETICION // DE CAMBIAR AL DIRECTORIO LUCHIN line = lector.readLine(); // VERIFICAR QUE LA RESPUESTA DEL SERVIDOR SEA CORRECTA // Y QUE HALLA DICHO QUE SE PUDO CAMBIAR AL DIRECTORIO // LUCHIN if (!line.startsWith("250 ")){ throw new IOException("La accin sobre fichero NO BIEN"); } else{ System.out.println("La accin sobre fichero SI BIEN"); } } catch(Exception e){ System.out.println(e.toString()); } } // Cierra MyApp public static void main(String args[]) MyApp f = new MyApp(); } Enciclopedia Conociendo {
184
Enciclopedia Conociendo
185
Enciclopedia Conociendo
186
Enciclopedia Conociendo
187
Enciclopedia Conociendo
188
Enciclopedia Conociendo
189
190
Enciclopedia Conociendo
191
EJB 1
MUERT O
EJB 2
MUERT O
Un Session Bean es un objeto que se instancia durante una sesin. Cada instancia es visible tan solo para un cliente. Para otro cliente es visible otra instancia de dicho Session Bean.
EJB SESSION
Instancia 1
CLIENTE1
CLIENTE2
CLIENTE3
Enciclopedia Conociendo
192
EJB SESSION
CLIENTE1
CONTEXTO
CLIENTE2
CLIENTE3
Instancia Local 1
EJB SESSION
Enciclopedia Conociendo
193
Cuando el cliente accede desde el mismo contexto accede a la instancia local, tal como se muestra en el siguiente grafico:
Instancia Local 1
EJB SESSION
Cliente1 Local
Instancia Remota 3 Y cuando el cliente accede desde un contexto diferente accede a la instancia remota del EJB de Session.
Instancia Local 1
EJB SESSION
Cliente1 Remoto
Cliente2 Remoto
Cliente3 Remoto
Enciclopedia Conociendo
194
Los Session Bean se pueden clasificar en Session Bean Stateless y Session Bean Statefull. Los Stateless no garantizan el almacenamiento del estado, tal como se muestra en la siguiente figura:
1 Cliente accede varias veces a la misma instancia Cliente 1 Local EJBSession.var = 20 x = EJBSession.getVar()
Instancia Local 1
La primera vez que usa el EJB de Session el cliente 1 le coloca a la variable el valor de 20 y la segunda vez que acceda al bean es posible que se halla perdido dicho valor. Este comportamiento se debe a que el EJB de Session es concretamente un EJB de Session stateless y no almacena el estado. Cuando se trata de Bean tipo statefull, el estado se almacena tal como muestra el diagrama siguiente:
1 Cliente accede varias veces a la misma instancia Cliente 1 Local EJBSession.var = 20 x = EJBSession.getVar()
Instancia Local 1
Cuando el EJB de Session es de tipo statefull decimos que todas las veces que acceda el cliente 1 a la instancia local 1 el valor ser el mismo siempre y cuando el valor no se modifique por un cliente, caso en el cual dichas modificaciones sern visibles en proximas consultas del EJB de Session statefull. En EJB3.0 no hay que crear descriptores de despliegue No hay que crear varios metodos callbacks que muchas veces no se usan. No hay que manejar multiples excepciones que ha veces son innecesarias. Se pude tener un EJB desde afuera del contenedor EJB Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva Con EJB3.0 se trabaja programacin orientada a atributos.
195
Enciclopedia Conociendo
196
Enciclopedia Conociendo
197
Enciclopedia Conociendo
198
Enciclopedia Conociendo
199
Enciclopedia Conociendo
200
Enciclopedia Conociendo
201
Enciclopedia Conociendo
202
Enciclopedia Conociendo
203
Se genera un codigo similar al siguiente: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package paquete1; import javax.ejb.Stateless; /** * * @author Luis Felipe Wanumen */ @Stateless public class NewSessionBean implements NewSessionRemote { public String getMessage() { return null; } // Add business logic below. (Right-click in editor and choose // "Insert Code > Add Business Method" or "Web Service > Add Operation") Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva } Le modificamos la parte del return y nos queda algo similar al siguiente:
204
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package paquete1; import javax.ejb.Stateless; /** * * @author Luis Felipe Wanumen */ @Stateless public class NewSessionBean implements NewSessionRemote { public String getMessage() { return "Hola Bean de Mensajeria"; } // Add business logic below. (Right-click in editor and choose // "Insert Code > Add Business Method" or "Web Service > Add Operation") } NeBeans automticamente crea la interfaz del Bean remoto similar a la siguiente: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package paquete1; import javax.ejb.Remote; /** * * @author Luis Felipe Wanumen */ @Remote public interface NewSessionRemote { String getMessage(); } Despus podemos crear un Servlet
Enciclopedia Conociendo
205
Enciclopedia Conociendo
206
Obviamente para que esto funcione se tuvo que haber creado el paquete 1 previamente en la parte del proyecto war. Creamos un servlet llamado TestServlet con el siguiente codigo: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package paquete1; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ejb.EJB; // import stateless.TestEJBRemote; /** * * @author Luis Felipe Wanumen Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva */ public class TestServlet extends HttpServlet { //This annotation INJECTS the TestEJBRemove object from EJB //into this attribute @EJB private NewSessionRemote testEJB; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Servlet TestServlet</title>"); out.println("</head>"); out.println("<body>"); out.println(testEJB.getMessage()); out.println("</body>"); out.println("</html>"); } }
207
Al ejecutar el Bean desde el entorno de desarrollo y por medio del navegador obtenemos un resultado similar al siguiente:
Enciclopedia Conociendo
208
Enciclopedia Conociendo
209
Enciclopedia Conociendo
210
SYSTEM
USUARIO
CODIGO NOMBRE
NUMBER VARCHAR2
Propi etario
Nombre d e l a T abl a
No mb re del ndi ce
Colu mn as
Uni ci dad
E st ad o
Tipo de ndice
Unir nd ice
SYSTEM
USUARIO
SYS_C003994
CODIGO
UNIQUE
VALID
NORMAL
NO
Enciclopedia Conociendo
211
Enciclopedia Conociendo
212
Enciclopedia Conociendo
213
Enciclopedia Conociendo
214
Enciclopedia Conociendo
215
Y usamos el asistente para crear una clase entidad de una base de datos:
Enciclopedia Conociendo
216
Enciclopedia Conociendo
217
Enciclopedia Conociendo
218
Enciclopedia Conociendo
219
Enciclopedia Conociendo
220
Enciclopedia Conociendo
221
El puerto es 1521
Enciclopedia Conociendo
222
Enciclopedia Conociendo
223
El nombre de usuario es: SYSTEM y el password es 123456 (en nuestro caso, obviamente esto depende de la instalacin).
Enciclopedia Conociendo
224
Enciclopedia Conociendo
225
NetBeans comienza a traer las tablas, segn el esquema de base de datos que se tiene en Oracle
Enciclopedia Conociendo
226
Al finalizar la incorporacin de datos del esquema se tiene una lista de tablas disponibles:
Enciclopedia Conociendo
227
Enciclopedia Conociendo
228
Aparece un warning que indica que el proyecto no tiene una unidad de persistencia.
Aparece una lista de proveedores de persistencia que pueden permitir la conexin con la base de datos
Enciclopedia Conociendo
229
Finalmente se crea la clase tipo Entity en el paquete paquete1: Existen varios tipos de mapeo a la base de datos:
Escogemos default
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva Existen varios tipos de colecciones y seleccionamos Collection
230
Enciclopedia Conociendo
231
Una vez terminado el proceso El crea un Bean que maneja la persistencia con la tabla usuario: Usuario.java /* * To change this template, choose Tools | Templates Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva * and open the template in the editor. */ package paquete1; import java.io.Serializable; import java.math.BigDecimal; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table;
232
/** * * @author Luis Felipe Wanumen */ @Entity @Table(name = "USUARIO", catalog = "", schema = "SYSTEM") @NamedQueries({@NamedQuery(name = "Usuario.findAll", query = "SELECT u FROM Usuario u"), @NamedQuery(name = "Usuario.findByCodigo", query = "SELECT u FROM Usuario u WHERE u.codigo = :codigo"), @NamedQuery(name = "Usuario.findByNombre", query = "SELECT u FROM Usuario u WHERE u.nombre = :nombre")}) public class Usuario implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @Column(name = "CODIGO", nullable = false, precision = 22, scale = 0) private BigDecimal codigo; @Column(name = "NOMBRE", length = 50) private String nombre; public Usuario() { } public Usuario(BigDecimal codigo) { this.codigo = codigo; } public BigDecimal getCodigo() { return codigo; } public void setCodigo(BigDecimal codigo) { this.codigo = codigo; } public String getNombre() { return nombre; }
Enciclopedia Conociendo
233
public void setNombre(String nombre) { this.nombre = nombre; } @Override public int hashCode() { int hash = 0; hash += (codigo != null ? codigo.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Usuario)) { return false; } Usuario other = (Usuario) object; if ((this.codigo == null && other.codigo != null) || (this.codigo != null && ! this.codigo.equals(other.codigo))) { return false; } return true; } @Override public String toString() { return "paquete1.Usuario[codigo=" + codigo + "]"; } }
Enciclopedia Conociendo
234
Enciclopedia Conociendo
235
Primero se observa que el servidor tenga correctamente configurada la tarjeta de red, debido a que se intenta en el ejercicio exponer un servicio web en donde un computador va a tener el servidor que hospeda el servicio web y otro equipo va a invocar dicho servicio:
Enciclopedia Conociendo
236
Enciclopedia Conociendo
237
Enciclopedia Conociendo
238
Ejecutamos la instruccin:
Enciclopedia Conociendo
239
Y nos damos cuenta que el servidor de servicios ha iniciado correctamente cuando aparece una pantalla similar a la siguiente:
Es importante notar que si se tiene algn servidor por el mismo puerto el anterior pantallazo no se presenta y en cambio se podra presentar un error similar al siguiente:
Enciclopedia Conociendo
240
Otra cosa importante de notar es que el servidor de servicios no siempre debe funcionar sobre el puerto 80 o el puerto 8080, una prueba de esto se muestra a continuacin:
Enciclopedia Conociendo
241
Enciclopedia Conociendo
242
Pero bueno, la verdad el ejercicio se hizo por un puerto estndar como lo es el 8080.
Enciclopedia Conociendo
243
En el lado del servidor y despus de haber instalado AXIS, se procede a tener en cuenta los sigueintes archivos:
C:\axis-1_4\lib\axis.jar; C:\axis-1_4\lib\axis-ant.jar; C:\axis-1_4\lib\commons-discovery-0.2.jar; C:\axis-1_4\lib\commons-logging-1.0.4.jar; C:\axis-1_4\lib\jaxrpc.jar; C:\axis-1_4\lib\log4j-1.2.8.jar; C:\axis-1_4\lib\saaj.jar; C:\axis-1_4\lib\wsdl4j-1.5.1.jar; C:\axis-1_4\lib\mail.jar; C:\axis-1_4\lib\activation.jar;
Para incluirlos dentro del CLASSPATH de la mquina, tal como se muestra a continuacin:
Enciclopedia Conociendo
244
Enciclopedia Conociendo
245
Enciclopedia Conociendo
246
Enciclopedia Conociendo
247
Enciclopedia Conociendo
248
Enciclopedia Conociendo
249
La cual comprueba que el servidor de servicios est completamente arriba. En caso que aparezca tal como se muestra a continuacin:
Enciclopedia Conociendo Curso de Jsp y Servlets
250
Quiere decir que est abajo, con lo cual se debe intentar comenzarlo haciendo click en el boton Start
Enciclopedia Conociendo
251
La anterior herramienta usa una maravillosa consola de administracin, la cual se muestra a continuacin:
Enciclopedia Conociendo
252
La cual permite crear un monitor en un determinado puerto con el fin de lograr que sta herramienta escuche lo que se enva por dicho puerto y cada vez que el servidor o un cliente hagan una transferencia de informacin por dicho puerto, saldr en la herramienta el contenido de lo que se enva y de lo que se recibe.
La herramienta tambin permite hacer una simulacin de las conexiones y esto se hace en la parte de abajo del monitor:
Enciclopedia Conociendo
253
En este caso, configuramos 4 bytes por pausa y le colocamos un regardo de 4 milisegundos para hacer la simulacin.
254
Enciclopedia Conociendo
255
Bueno, en el anterior caso lo hicimos con localhost, pero tambin lo pudimos haber hecho con felipe, tal como se muestra a continuacin:
Enciclopedia Conociendo
256
Y el archivo wsdl:
Enciclopedia Conociendo
257
Enciclopedia Conociendo
258
Enciclopedia Conociendo
259
Vemos que all se muestran problemas de configuracin que es necesario ajustarlos antes de continuar con el ejercicio, debido a que el servidor si no funciona correctamente, la aplicacin por tanto no se ver y se tuvieron que instalar otras versiones de AXIS, que fueran compatibles, tambin suceda esto porque haba un archivo de configuracin que estaba daado y cada vez que se instalaba el AXIS, se copiaba, pero en s el archivo estaba daado, dicho archivo conflictivo fue:
mail.jar
Enciclopedia Conociendo Curso de Jsp y Servlets
260
Despus de probar que ste era el archivo que estaba daado, proced a bajar de otro sitio el AXIS, y salo un pantallazo similar al siguiente:
261
xmlns:impl="http://xml.apache.org/axis/wsdd/" xmlns:intf="http://xml.apache.org/axis/wsdd/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> Error!Referencia de hipervnculo no vlida. <!-WSDL created by Apache Axis version: 1.4 Built on Apr 22, 2006 (06:55:48 PDT) --> Error!Referencia de hipervnculo no vlida. <wsdl:types> Error!Referencia de hipervnculo no vlida. <schema targetNamespace="http://xml.apache.org/axis/wsdd/" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="AdminService" type="xsd:anyType" /> <element name="AdminServiceReturn" type="xsd:anyType" /> </schema> </wsdl:types> Error!Referencia de hipervnculo no vlida. <wsdl:message name="AdminServiceRequest"> <wsdl:part element="impl:AdminService" name="part" /> </wsdl:message>
Enciclopedia Conociendo
262
Error!Referencia de hipervnculo no vlida. <wsdl:message name="AdminServiceResponse"> <wsdl:part element="impl:AdminServiceReturn" name="AdminServiceReturn" /> </wsdl:message> Error!Referencia de hipervnculo no vlida. <wsdl:portType name="Admin"> Error!Referencia de hipervnculo no vlida. <wsdl:operation name="AdminService"> <wsdl:input message="impl:AdminServiceRequest" name="AdminServiceRequest" /> <wsdl:output message="impl:AdminServiceResponse" name="AdminServiceResponse" /> </wsdl:operation> </wsdl:portType> Error!Referencia de hipervnculo no vlida. <wsdl:binding name="AdminServiceSoapBinding" type="impl:Admin"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> Error!Referencia de hipervnculo no vlida. <wsdl:operation name="AdminService"> <wsdlsoap:operation soapAction="" />
Enciclopedia Conociendo
263
Error!Referencia de hipervnculo no vlida. <wsdl:input name="AdminServiceRequest"> <wsdlsoap:body use="literal" /> </wsdl:input> Error!Referencia de hipervnculo no vlida. <wsdl:output name="AdminServiceResponse"> <wsdlsoap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> Error!Referencia de hipervnculo no vlida. <wsdl:service name="AdminService"> Error!Referencia de hipervnculo no vlida. <wsdl:port binding="impl:AdminServiceSoapBinding" name="AdminService"> <wsdlsoap:address location="http://felipe:8080/axis/services/AdminService" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
Enciclopedia Conociendo
264
public class HolaMundo { public String hola(String nombre) { return new String("Hola " + nombre + "!"); } }
Enciclopedia Conociendo
265
Enciclopedia Conociendo
266
Fisicamente el cliente se prob en una mquina conectada a "Felipe", la cual es una mquina con la siguiente configuracin de red:
Enciclopedia Conociendo
267
Dicha mquina se llama Esmeralda y antes de probar el aplicativo, primero se prob que tuviera conexin con el servidor, lo cual se hizo de la siguiente manera:
Una vez ya se sabe que se tiene conexin fisica, se procede a crear el archivo siguiente en un entorno de desarrollo:
268
public class HolaMundoClient { public static void main(String [] args) throws Exception {
call.setTargetEndpointAddress( new java.net.URL(endpoint) ); call.setOperationName( "hola" ); call.addParameter( "nombre", XMLType.XSD_STRING, ParameterMode.IN ); call.setReturnType( XMLType.XSD_STRING );
Enciclopedia Conociendo
269
Y antes de ejecutar el servidor, se verifica si el servidor de servicios osea el web service funciona correctmente, y esto se hizo abriendo el navegador y ejecutando la linea:
http://felipe:8080
Enciclopedia Conociendo
270
Enciclopedia Conociendo
271
Y adicionalmente se hicieron las referencias respectivas para incluir los paquetes necesarios para que el servicio web funcionara:
Enciclopedia Conociendo
272
Enciclopedia Conociendo
273
Y con el nimo de hacer la vida bastante fcil, se us "realJ" para la creacin de un archivo con extensin ".bat" que permitiera la ejecucin de dicho programa:
Enciclopedia Conociendo
274
Enciclopedia Conociendo
275
Enciclopedia Conociendo
276
277
Enciclopedia Conociendo
278
Y para comprobar que la cuestin anda bien, tambin se ejecut desde la propia herramienta de desarrollo, en este caso desde "realJ", dando el resultado mostrado a continuacin:
Enciclopedia Conociendo
279
Enciclopedia Conociendo
280
Enciclopedia Conociendo
281
Enciclopedia Conociendo
282
Enciclopedia Conociendo
283
Observe que lo puede ejecutar sin necesidad de tantos comandos, simplemente ejecutando el ".bat".
Obviamente para lograr que esta ejecucin se realice de la mejor forma, se debe tener cuidado que los archivos
284
Se encuentren dentro de un directorio en el raiz, denominado "lib", tal como se muestra a continuacin:
Tambin se debe verificar que el cliente tenga una mquina virtual apropiada y esto se puede hacer con el comando java - version.
Enciclopedia Conociendo
285
Enciclopedia Conociendo
286
Enciclopedia Conociendo
287
Enciclopedia Conociendo
288
Clase 1
Clase 2
Clase 3
Clase 4
Clase 1
Los casos de prueba pueden agruparse segn su funcionalidad en suites de prueba (test suite), lo cual grficamente puede verse como se muestra a continuacin:
Enciclopedia Conociendo
289
Podemos seguir agrupando suites de prueba en suites de prueba con lo cual tenemos una estructura similar a la siguiente:
Con lo cual vemos que las suites de prueba se organizan en forma de rbol y cuando aplicamos una suite de pruebas ejecutamos las suites de pruebas que se encuentran dentro de esta suite de prueba. Obviamente esto permite acelerar el proceso de testeo de aplicaciones, debido a que permite aplicar todo un subrbol o un rbol a un conjunto de clases.
290
public class Lista{ Nodo cabeza = null; Nodo ultimo = null; public boolean buscarNodo(int valor){ boolean buscado = false; if(cabeza==null){ return buscado; } // Cierra if externo else{ Nodo correr = cabeza; while(correr!=null){ if(correr.valor==valor){ buscado = true; break; } correr = correr.siguiente; } // Cierra while } // Cierra else externo return buscado; } // Cierra boolean buscarNodo // Ingresa elementos a la lista sin importar // si los elementos ya se encuentran, tampoco // importa el orden, siempre lo dejara al // final de la lista el ultimo elemento // ingresado. public void ingresarNodo(int valor){ boolean encontrado = buscarNodo(valor); if(!encontrado){ Nodo nuevo = new Nodo(); nuevo.valor = valor; if(cabeza==null){ cabeza = nuevo; ultimo = nuevo; } else{ Nodo antes = cabeza; Nodo despues = cabeza; while(despues!=null){ if(despues.valor>valor){ break; } antes = despues; despues = despues.siguiente; } // Cierra while interno antes.siguiente = nuevo; nuevo.siguiente = despues; } // else interno } // Entra al if cuando no existe Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva } // Cierra void ingresarNodo() public String getListado(){ Nodo correr = cabeza; String cadena = ""; while(correr!=null){ cadena = cadena + correr.valor; cadena = cadena + " "; correr = correr.siguiente; } // Cierra while return cadena; } // Cierra String imprimirLista() public Lista(Nodo nodin){ cabeza = nodin; Nodo corre = cabeza; while(corre!=null){ if(corre.siguiente==null){ ultimo = corre; } corre = corre.siguiente; } // Cierra while }// Cierra public MyApp() public boolean comparar(Lista objeto){ boolean retornar=true; if(objeto!=null){ Nodo correr1 = cabeza; Nodo correr2 = objeto.cabeza; // Nodo correr2 = objeto.cabeza.siguiente; while(correr1!=null){ if(correr1.valor!=correr2.valor){ retornar = false; } correr1 = correr1.siguiente; correr2 = correr2.siguiente; if(correr1==null && correr2!=null){ retornar = false; } if(correr1!=null && correr2==null){ retornar = false; } } // Cierra while if(correr2!=null){ retornar = false; } return retornar; } // Cierra if externo return false; } // Cierra boolean comparar } // Cierra class Lista
291
Enciclopedia Conociendo
292
Realmente el objetivo de la creacin de la clase anterior es tener una clase que permita adicionar elementos a la lista, teniendo en cuenta que el comienzo de la lista esta referenciado por una variable llamada cabeza. La insercin de elementos en la lista se hace con el mtodo ingresarNodo(int). Dicho mtodo verifica que no existan elementos en la lista mediante la invocacin del mtodo boolean buscarNodo(int valor), el cual retorna true cuando existe en la lista un Nodo cuyo valor es igual al solicitado, el mtodo retorna false en caso que no exista coincidencia alguna. La lista permite el ingreso de elementos en forma ordenada y ascendente segn el valor contenido en la variable valor de cada Nodo. El amigo lector / estudiante se estar preguntando: Por qu incluir mas mtodos si solamente se va a probar el mtodo ingresarNodo(int)?. La respuesta es bien sencilla: Se requieren otros mtodos para que Junit logre probar correctamente el mtodo ingresarNodo(int) y tambin se requieren otros mtodos para que en si el mtodo funcione. Detalladamente podemos decir que el mtodo String getListado() se coloco como un ejercicio suelto porque ni es necesario para que funcione Junit, ni es necesario para que funcione la insercin. De otra parte el mtodo boolean buscarNodo(int valor) es necesario para que funcione el mtodo ingresarNodo(int). El constructor de la clase Lista es necesario simplemente para garantizar que cuando se cree una lista, es porque existe por lo menos un primer elemento cabeza que se debe almacenar en mencionada lista. Finalmente decimos que la clase Lista tiene un mtodo llamado boolean comparar(Lista objeto) y este mtodo es necesario para que funcione Junit, debido a que es con la invocacin de este mtodo que vamos a comparar dos listas, una que se construye manualmente y otra que se construye invocando el mtodo ingresarNodo(int) de la clase Lista. Esta ultima parte se explicara con detalle cuando se este explicando el testeo de la aplicacin.
Enciclopedia Conociendo
293
Ahora creamos un mtodo llamado testIngresarNodo() con el que probaremos el mtodo ingresarNodo(int) de la clase Lista. Veamos entonces detenidamente como es que funciona el mtodo para el testeo. Creamos manualmente 5 nodos con el estereotipo static: final static Nodo nodo1Lista2 = new Nodo(); final static Nodo nodo2Lista2 = new Nodo(); final static Nodo nodo3Lista2 = new Nodo(); final static Nodo nodo4Lista2 = new Nodo(); final static Nodo nodo5Lista2 = new Nodo(); Les asignamos unos valores: nodo1Lista2.valor nodo2Lista2.valor nodo3Lista2.valor nodo4Lista2.valor nodo5Lista2.valor = = = = = 1; 5; 2; 3; 4;
Los ingresamos a la lista usando el metodo ingresarNodo(int): Lista listaPROBANO = new Lista(nodo1Lista2); listaPROBANO.ingresarNodo(nodo1Lista2.valor); listaPROBANO.ingresarNodo(nodo2Lista2.valor); listaPROBANO.ingresarNodo(nodo3Lista2.valor); listaPROBANO.ingresarNodo(nodo4Lista2.valor); listaPROBANO.ingresarNodo(nodo5Lista2.valor); Se supone que si el mtodo funciona como debe funcionar correctamente la lista tendra los siguientes nodos: 1 2 3 4 5 listaPROBANO
Recordemos que esto debera funcionar debido a que en teoria el metodo ingresarNodo(int) ingresa elementos siempre y cuando no existan y los va ingresando en forma ordenada ascendentemente. Ahora bien, vamos a proceder a realizar una lista que con seguridad sabemos que forma tiene, debido a que se ha hecho en forma manual: Lista listaBIEN = new Lista(nodo1Lista1); final final final final final static static static static static Nodo Nodo Nodo Nodo Nodo nodo1Lista1 nodo2Lista1 nodo3Lista1 nodo4Lista1 nodo5Lista1 = = = = = new new new new new Nodo(); Nodo(); Nodo(); Nodo(); Nodo();
Y la enlazamos manualmente tal como se muestra a continuacin: nodo1Lista1.siguiente = nodo2Lista1; nodo2Lista1.siguiente = nodo3Lista1; nodo3Lista1.siguiente = nodo4Lista1;
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva nodo4Lista1.siguiente = nodo5Lista1; Obviamente tenemos grficamente una lista similar a la siguiente: 1 2 3 4 5 listaBIEN
294
Las comparamos e informamos a Junit el resultado de dicha comparacin invocando el mtodo assertTrue(boolean x). Junit se encargara automticamente de verificar que el mtodo funcione como queremos que funcione. Observemos tambin que con esta forma de hacer pruebas uno puede definir manualmente los objetos que producen los mtodos que se van a probar y luego al ser comparados con los verdaderos objetos que retorna la ejecucin de estos mtodos podremos saber si realmente funcionan nuestros mtodos como lo esperbamos. Veamos pues el cdigo completo de nuestra clase de testeo: ListaTest.java import junit.framework.*; public class ListaTest extends TestCase{ final final final final final final final final final final static static static static static static static static static static Nodo Nodo Nodo Nodo Nodo Nodo Nodo Nodo Nodo Nodo nodo1Lista1 nodo2Lista1 nodo3Lista1 nodo4Lista1 nodo5Lista1 nodo1Lista2 nodo2Lista2 nodo3Lista2 nodo4Lista2 nodo5Lista2 = = = = = = = = = = new new new new new new new new new new Nodo(); Nodo(); Nodo(); Nodo(); Nodo(); Nodo(); Nodo(); Nodo(); Nodo(); Nodo();
public void testIngresarNodos(){ nodo1Lista1.siguiente nodo2Lista1.siguiente nodo3Lista1.siguiente nodo4Lista1.siguiente nodo1Lista1.valor nodo2Lista1.valor nodo3Lista1.valor nodo4Lista1.valor nodo5Lista1.valor nodo1Lista2.valor nodo2Lista2.valor nodo3Lista2.valor nodo4Lista2.valor Enciclopedia Conociendo = = = = = = = = = 1; 2; 3; 4; 5; 1; 5; 2; 3; Curso de Jsp y Servlets = = = = nodo2Lista1; nodo3Lista1; nodo4Lista1; nodo5Lista1;
Autor: Luis Felipe Wanumen Silva nodo5Lista2.valor = 4; Lista listaBIEN = new Lista(nodo1Lista1); Lista listaPROBANO = new Lista(nodo1Lista2); listaPROBANO.ingresarNodo(nodo1Lista2.valor); listaPROBANO.ingresarNodo(nodo2Lista2.valor); listaPROBANO.ingresarNodo(nodo3Lista2.valor); listaPROBANO.ingresarNodo(nodo4Lista2.valor); listaPROBANO.ingresarNodo(nodo5Lista2.valor); assertTrue(listaBIEN.comparar(listaPROBANO)); } // Cierra void testIngresarNodos() public ListaTest(String nombre){ super(nombre); } // Cierra constructor ListaTest() } // Cierra class ListaTest
295
Enciclopedia Conociendo
296
En donde podemos escoger la ficha que muestra el rbol de pruebas, el cual nos presenta una interfaz similar a la siguiente:
Enciclopedia Conociendo
297
Observamos pues que para nuestro ejercicio el metodo testIngresarNodos responde satisfactorio en la ejecucin de las pruebas. Para comprobar que esto realmente es cierto vamos a modificar la clase Lista y la dejaremos tal como se muestra a continuacin: Lista.java import java.awt.*; import java.awt.event.*; public class Lista{ Nodo cabeza = null; Nodo ultimo = null; public boolean buscarNodo(int valor){ boolean buscado = false; if(cabeza==null){ return buscado; } // Cierra if externo else{ Nodo correr = cabeza; Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva while(correr!=null){ if(correr.valor==valor){ buscado = true; break; } correr = correr.siguiente; } // Cierra while } // Cierra else externo return buscado; } // Cierra boolean buscarNodo // Ingresa elementos a la lista sin importar // si los elementos ya se encuentran, tampoco // importa el orden, siempre lo dejara al // final de la lista el ultimo elemento // ingresado. public void ingresarNodo(int valor){ boolean encontrado = buscarNodo(valor); if(!encontrado){ Nodo nuevo = new Nodo(); nuevo.valor = valor; if(cabeza==null){ cabeza = nuevo; ultimo = nuevo; } else{ Nodo antes = cabeza; Nodo despues = cabeza; while(despues!=null){ if(despues.valor>valor){ break; } // LO DEJAMOS EN COMENTARIO PARA // QUE ESTO INTENCIONALMENTE FUNCIONE // MAL Y PROVOQUE QUE EL JUNIT // INFORME DE UN ERROR POR AQUI. // antes = despues; despues = despues.siguiente; } // Cierra while interno antes.siguiente = nuevo; nuevo.siguiente = despues; } // else interno } // Entra al if cuando no existe } // Cierra void ingresarNodo() public String getListado(){ Nodo correr = cabeza; String cadena = ""; while(correr!=null){ cadena = cadena + correr.valor; cadena = cadena + " "; Enciclopedia Conociendo
298
Autor: Luis Felipe Wanumen Silva correr = correr.siguiente; } // Cierra while return cadena; } // Cierra String imprimirLista() public Lista(Nodo nodin){ cabeza = nodin; Nodo corre = cabeza; while(corre!=null){ if(corre.siguiente==null){ ultimo = corre; } corre = corre.siguiente; } // Cierra while }// Cierra public MyApp() public boolean comparar(Lista objeto){ boolean retornar=true; if(objeto!=null){ Nodo correr1 = cabeza; Nodo correr2 = objeto.cabeza; // Nodo correr2 = objeto.cabeza.siguiente; while(correr1!=null){ if(correr1.valor!=correr2.valor){ retornar = false; } correr1 = correr1.siguiente; correr2 = correr2.siguiente; if(correr1==null && correr2!=null){ retornar = false; } if(correr1!=null && correr2==null){ retornar = false; } } // Cierra while if(correr2!=null){ retornar = false; } return retornar; } // Cierra if externo return false; } // Cierra boolean comparar } // Cierra class Lista Al ejecutar el Junit con este error, tenemos un pantallaza similar al siguiente:
299
Enciclopedia Conociendo
300
Enciclopedia Conociendo
301
Enciclopedia Conociendo
302
En el siguiente programa se tiene un MIDLET bsico: import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class Celular1 extends MIDlet { public Celular1() { // constructor } public void startApp() { Canvas canvas = new MiTablero(); Display display = Display.getDisplay(this); display.setCurrent(canvas); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } class MiTablero extends Canvas { public void paint(Graphics g){ // Establece color a AZUL g.setColor(0, 0, 255); g.fillRect(0, 0, (int)(getWidth()/2), getHeight()); g.drawString("Pantallazo 1", 0, 0, g.TOP | g.LEFT); } } Enciclopedia Conociendo Curso de Jsp y Servlets
303
En el cual la clase que extiende de MIDLET se llama Celular1 y contiene los tres mtodos que gestionan el estado del MIDLET, pero el nico mtodo de estos tres que tiene cdigo es el startApp() el cual coloca un lienzo e la pantalla del dispositivo ligero. La forma de colocar elementos en un dispositivo ligero esta dada por los siguientes pasos: Se obtiene una referencia al dispositivo de pantalla fsico. Se crean los objetos que se quieren colocar en la pantalla. Usando la referencia al dispositivo ligero se colocan los objetos previamente creados.
En la siguiente tabla se aclaran cuales son las instrucciones del anterior programa que hacen cada una de las acciones mencionadas: ACCION Se obtiene una referencia al dispositivo de pantalla fsico. Se crean los objetos que se quieren colocar en la pantalla. Usando la referencia al dispositivo ligero se colocan los objetos previamente creados. CODIGO Canvas canvas = new MiTablero(); Display display Display.getDisplay(this); display.setCurrent(canvas); =
Hay que tener en cuenta que el MIDLET del que estamos hablando tambin define otro mtodo que se llama Celular1(), pero este mtodo no hace labor alguna, razn por la cual en este momento tan solo nos limitaremos a decir que es el mtodo constructor del MIDLET. Finalmente el MIDLET que estamos estudiando tiene una clase interna que tiene el siguiente cdigo: class MiTablero extends Canvas { public void paint(Graphics g){ // Establece color a AZUL g.setColor(0, 0, 255); g.fillRect(0, 0, (int)(getWidth()/2), getHeight()); g.drawString("Pantallazo 1", 0, 0, g.TOP | g.LEFT); } } Esta clase es similar a un applet y para los amigos familiarizados con Java, diremos que se comporta como un applet y por tanto tiene los mtodos normales de un applet. Es como hacer un applet y colocarlo como un lienzo en la pantalla del dispositivo ligero. Esto es una idea intuitiva que ayuda a comprender el funcionamiento de los lienzos en Java. En este caso este lienzo define el modo grafico en color azul, de tal forma que las siguientes cosas que pinte se pintaran de color azul, a continuacin se hace un rectngulo rellenado de color azul, el cual ocupa la mitad de la pantalla del dispositivo ligero y finalmente se coloca un letrero en color azul que dice Pantallaza 1 con lo cual la ejecucin del programa anterior produce unos resultados grficos similares a los siguientes:
Enciclopedia Conociendo
304
La pregunta es: Por qu no aparece el letrero: Pantallaza 1?, la respuesta es: porque esta del mismo color del fondo, con lo cual se hace necesario hacer la modificacin que a continuacin se muestra: public void paint(Graphics g){ // Establece color a AZUL Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva g.setColor(0, 0, 255); g.fillRect(0, 0, (int)(getWidth()/2), getHeight()); g.setColor(0, 255, 255); g.drawString("Pantallazo 1", 0, 0, g.TOP | g.LEFT); } Con lo cual se tiene un resultado grafico similar al siguiente:
305
Enciclopedia Conociendo
306
Enciclopedia Conociendo
307
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva El cual grficamente puede ser visualizado de la siguiente manera:
308
Enciclopedia Conociendo
309
Autor: Luis Felipe Wanumen Silva } // Cierra class Tablero3 } // Cierra class Celular1 El cual genera el siguiente resultado:
310
Enciclopedia Conociendo
311
Enciclopedia Conociendo
312
Enciclopedia Conociendo
313
De tal forma que cuando seleccionamos la aplicacin el dispositivo nos muestra la forma que hemos tal como se muestra a continuacin:
Enciclopedia Conociendo
314
Observe amigo lector / estudiante que si no hubiera sido por la instruccin siguiente: display.setCurrent(forma);
Enciclopedia Conociendo
315
no se habra podido producir este efecto y tan solo se hubiera visto el nombre de la aplicacin, pero no se habra podido ver el efecto descrito en este ultimo pantallaza.
Enciclopedia Conociendo
316
Enciclopedia Conociendo
317
Autor: Luis Felipe Wanumen Silva cadena1.setText("2"); } if(c==tres){ cadena1.setText("3"); } } // Cierra void commandAction()
318
Ahora bien, con el nimo de ser lo ms didcticos posibles, a continuacin se muestra el MIDLET que contiene el cdigo completo del ejercicio que nos proponemos en esta seccin: import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class Celular1 extends MIDlet implements CommandListener{ Display display; Form forma; StringItem cadena1; Command uno; Command dos; Command tres; // javax.microedition.lcdui.Command // javax.microedition.lcdui.Displayable public void commandAction(Command c,Displayable d){ if(c==uno){ cadena1.setText("1"); } if(c==dos){ cadena1.setText("2"); } if(c==tres){ cadena1.setText("3"); } } // Cierra void commandAction() public Celular1() { // constructor forma = new Form("Primer forma"); cadena1 = new StringItem("","Soy un ITEM"); uno = new Command("UNO",Command.SCREEN,1); dos = new Command("DOS",Command.SCREEN,2); tres = new Command("TRES",Command.SCREEN,3); forma.addCommand(uno); forma.addCommand(dos); forma.addCommand(tres); forma.setCommandListener(this); forma.append(cadena1); } // Cierra public Celular1 public void startApp() { display = Display.getDisplay(this); display.setCurrent(forma); } Enciclopedia Conociendo Curso de Jsp y Servlets
319
public void pauseApp() { } public void destroyApp(boolean unconditional) { } } // Cierra class Celular1 La ejecucin del anterior programa produce un resultado similar al siguiente:
Enciclopedia Conociendo
320
En donde se puede apreciar que aparece un Menu en la parte inferior izquierda que nos permite desplegar un Men cuando pulsamos el botn que se encuentra justo debajo de esta palabra, obteniendo un resultado similar al siguiente:
Enciclopedia Conociendo
321
El amigo lector / estudiante puede comprobar que llegados a este punto, es posible presionar el botn 1 para ejecutar la instruccin: cadena1.setText("1"); Enciclopedia Conociendo Curso de Jsp y Servlets
322
y en forma anloga si se presiona el botn 2 se ejecuta la instruccin: cadena1.setText("2"); y finalmente si se presiona el botn 3 se ejecuta la instruccin: cadena1.setText("3"); Para este caso, hemos presionado el botn 2, con lo cual obtenemos el resultado:
Enciclopedia Conociendo
323
Es bueno tener en cuenta que esto se puede tambin hacer presionando el botn del centro llamado select cuando la opcin del men correspondiente esta seleccionada, es decir para este caso cuando este seleccionada la opcin 2:
Enciclopedia Conociendo
324
Enciclopedia Conociendo
325
public class Tecno extends MIDlet implements CommandListener{ private TextField caja1; private TextField caja2; private Form formulario; private Command comandoBuscar = new Command("Busca", Command.OK, 1); private String direccion = "http://localhost:1900/examples/servlet/MyApp?codigo="; public class Hilo extends Thread{ public void run(){ try{ StringBuffer objetoBuffer = new StringBuffer(); InputStream objetoEntrada = null; HttpConnection objetoConector = null; String codi; codi = caja1.getString(); objetoConector = (HttpConnection)Connector.open(direccion+codi); objetoEntrada = objetoConector.openInputStream(); int caracter=0; while((caracter= objetoEntrada.read())!=-1){ objetoBuffer.append((char)caracter); } caja2.setString(objetoBuffer.toString());
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva } // Cierra try catch(Exception e){ } } // Cierra run } public void destroyApp(boolean boleano){ } public void pauseApp(){ } public void startApp(){ formulario = new Form("Soy Forma1"); caja1 = new TextField("Cedula", "", 15, TextField.ANY); formulario.append(caja1); caja2 = new TextField("Nombre", "", 15, TextField.ANY); formulario.append(caja2); formulario.addCommand(comandoBuscar); formulario.setCommandListener(this); Display.getDisplay(this).setCurrent(formulario); } public Tecno(){ } public void commandAction(Command c, Displayable s) { if (c == comandoBuscar) { // caja1.setString("Ponchado"); Hilo miHilo = new Hilo(); try{ miHilo.start(); } catch(Exception e){ } // Cierra catch } // Cierra commandAction } // Cierra Tecno }
326
Enciclopedia Conociendo
327
Despus cree un archivo con el nombre dos.java, el cual contenga el siguiente cdigo: import javax.microedition.lcdui.*; import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Form; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import java.io.*; import javax.microedition.io.*;
Enciclopedia Conociendo
328
import java.io.*; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import org.ksoap.*; import org.ksoap.transport.HttpTransport; import org.kxml.*; import org.kxml.parser.*;
public class dos extends MIDlet implements CommandListener { Form mainForm; private Alert response; static final String serviceNamespace = "http://localhost:8080/axis/servicio.jws:http://DefaultNamespace:http://localhost:8080/ axis/servicio.jws"; static final String serviceUrl = "http://localhost:8080/axis/servicio.jws?wsdl"; static final String methodName = "saludar"; private Display display; static final String soapAction = " "; // Display display; static final String entrada = "saludarRequest"; // private SoapObject request; private ClassMap classMap; private HttpTransport transport; private SoapObject request; // private ClassMap classMap; Hilo objeto = new Hilo(); public class Hilo extends Thread{ public Hilo(){ } public void run(){ response = new Alert( "Weather Status", null, null, AlertType.INFO); response.setTimeout( Alert.FOREVER );
Enciclopedia Conociendo
329
transport = new HttpTransport(serviceUrl, soapAction + "#" + methodName ); transport.debug = true; classMap = new ClassMap(); classMap.prefixMap = new PrefixMap( classMap.prefixMap, entrada, serviceNamespace ); transport.setClassMap( classMap ); request = new SoapObject( serviceNamespace, methodName ); request.addProperty( "nombrecin", "LUCHIN" ); try{ Object result = transport.call( request ); String resultado = (String)result; response.setString( resultado ); display.setCurrent( response ); } catch(Exception e){ }
} } public dos() { mainForm = new Form("Text Field"); display = Display.getDisplay( this ); try{ objeto.start(); } catch(Exception e){ } } protected void startApp() { display.setCurrent(mainForm); } public void commandAction(Command c, Displayable s) { }
Enciclopedia Conociendo Curso de Jsp y Servlets
330
Despues dentro de la carpeta AXIS del servidor de servicios web cree un archivo llamado servicio.jws que contenga el siguiente cdigo: public class servicio{ public String saludar(String nombrecin){ String interno; interno = "Buenas noches "+nombrecin; return interno; } } Es bueno observar que si se entra a la siguiente direccin en el navegador, http://localhost:8080/axis/servicio.jws se tiene siguiente resultado:
Enciclopedia Conociendo
331
332
<wsdlsoap:operation soapAction="" /> - <wsdl:input name="saludarRequest"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://DefaultNamespace" use="encoded" /> </wsdl:input> - <wsdl:output name="saludarResponse"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/servicio.jws" use="encoded" /> </wsdl:output> </wsdl:operation> </wsdl:binding> - <wsdl:service name="servicioService"> - <wsdl:port binding="impl:servicioSoapBinding" name="servicio"> <wsdlsoap:address location="http://localhost:8080/axis/servicio.jws" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
Enciclopedia Conociendo
333
Enciclopedia Conociendo
334
El cual nos indica que tenemos que conectarnos a un servidor y le decimos que si, con lo cual obtenemos lo siguiente:
Enciclopedia Conociendo
335
Enciclopedia Conociendo
336
import javax.bluetooth.UUID; import javax.microedition.io.StreamConnectionNotifier; import javax.microedition.io.Connector; import javax.microedition.io.StreamConnection; import java.io.IOException; import java.io.OutputStream; import java.io.DataOutputStream; public class Bluetooth1 extends MIDlet{ public static Display objetoDisplay; public static Form objetoForma; private LocalDevice localDevice; private TextField caja1; private TextField caja2; private TextField caja3; private TextField caja4; private TextField caja5; private TextField caja6; Enciclopedia Conociendo Curso de Jsp y Servlets
337
private static final UUID identificadorServicio = new UUID("F0E0D0C0B0A000908070605040302010", false); // Notificador para aceptar conecciones private StreamConnectionNotifier notificador; // Maneja la coneccion con el cliente StreamConnection coneccion; OutputStream out = null; // Hilo para atender a clientes Hilo objetoHilo = new Hilo(); public void destroyApp(boolean x){ } public void pauseApp(){ } public void startApp(){ objetoDisplay = Display.getDisplay(this); objetoForma = new Form("Formulario1"); caja1 = new TextField("Estado Dispositivo Bluetooth","texto",40,TextField.ANY); caja2 = new TextField("Servidor y UUID Bluetooth","texto",60,TextField.ANY); caja3 = new TextField("NombreServicio Bluetooth","texto",80,TextField.ANY); caja4 = new TextField("Servicio Bluetooth Completo","texto",100,TextField.ANY); caja5 = new TextField("Estado Servicio Nuestro","texto",120,TextField.ANY); caja6 = new TextField("Estado coneccion Cliente","texto",120,TextField.ANY); objetoDisplay.setCurrent(objetoForma); objetoForma.append(caja1); objetoForma.append(caja2); objetoForma.append(caja3); objetoForma.append(caja4); objetoForma.append(caja5); objetoForma.append(caja6); try { // consigue referencia al dispositivo local localDevice = LocalDevice.getLocalDevice(); if (!localDevice.setDiscoverable(DiscoveryAgent.GIAC)){ caja1.setString("NO Pudo crear dispositivo"); } else{ caja1.setString("SE Pudo crear dispositivo"); Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva } // prepara una URL para crear un notificador StringBuffer url = new StringBuffer("btspp://"); // indicate que este es un servidor url.append("localhost").append(':'); // adiciona el identificador UUID para este servicio url.append(identificadorServicio.toString()); caja2.setString(url.toString()); // adicionamos el nombre de nuestro servicio url.append(";name=ServicioSaludar"); caja3.setString(url.toString()); // Informa a los clientes que no requieren // autorizacion para conectarse // Algunos dispositivos fallan cuando se coloca // authorize=true url.append(";authorize=false"); caja4.setString(url.toString()); // Crea un notificador ahora notificador = (StreamConnectionNotifier)Connector.open(url.toString()); if(notificador==null){ caja5.setString("Fallo al iniciar Servidor Bluetooth"); } else{ caja5.setString("Pudo iniciar Servidor Bluetooth bien"); } try{ objetoHilo.start(); } catch(Exception e){ caja6.setString("Problemas con el HILO"); }
338
} // Cierra try externo catch(Exception e){ Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva caja6.setString("Algo pasa"); } } // Cierra void startApp public class Hilo extends Thread{ public void run(){ while(true){ try{ caja6.setString("Esperando cliente"); coneccion = notificador.acceptAndOpen(); caja6.setString("Llego un cliente"); // Cuando llega el cliente le // enviamos un saludo out = coneccion.openOutputStream(); DataOutputStream salida = new DataOutputStream(out); salida.writeUTF("Buenas"); salida.flush(); } // Cierra try externo catch(IOException e){ caja6.setString("No llega cliente alguno"); } // Cierra catch interno } // Cierra while } // Cierra run() } // Cierra class Hilo }
339
El siguiente es un ejemplo sencillo de comunicacin entre celulares usando la tecnologa bluetooth, en nuestro ejercicio veremos que lo mas sencillo es la implementacin del Servidor Bluetooth debido a que el servidor atiene a clientes y no tiene que buscar servicios en los clientes, en cambio el cliente tiene que buscar dispositivos servidores e intentar conectarse con los servicios que estan en dichos dispositivos.
340
StringBuffer url = new StringBuffer("btspp://localhost:"); url.append(SERVICIO_CHAT.toString()); url.append(";name=Servicio chat;authorize=true"); Realmente el servicio bluetooth usa un notificador que se crea con la clase Connector StreamConnectionNotifier notifier = (StreamConnectionNotifier)Connector.open(url.toString()); La cual acepta conexiones aceptando y abriendo conexiones con los distintos clientes en forma indefinida, es decir admite tantas conexiones como la capacidad del dispostivo lo permita, esto se logra con un ciclo infinito: StreamConnection connection = null; DataInputStream in = null; DataOutputStream out = null; while(true) { try { connection = notifier.acceptAndOpen(); in = connection.openDataInputStream(); out = connection.openDataOutputStream(); out.writeUTF("Servidor: HOLA MUNDO"); out.flush(); String s = in.readUTF(); System.out.println("Cliente dice"+s); System.out.println(s); } De todas formas, sea que se pueda o no crear los flujos de entrada o de salida para leer lo que los clientes envian o el flujo para enviarle a los clientes de parte del servidor, es necesario hacer una verificacin de si se pudieron crear dichos objetos para luego liberar los recursos de estos flujos, esto se logra con las instrucciones: try { if(in != null) in.close(); if(out != null) out.close(); if(connection != null) connection.close(); } Para lograr una mayor comprensin de este servidor Bluetooth, a continuacin se muestra el programa completo que implementa el servidor Bluetooth. import import import import import javax.microedition.midlet.MIDlet; javax.microedition.lcdui.*; javax.bluetooth.*; javax.microedition.io.*; java.io.*; Curso de Jsp y Servlets
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva public class ServidorB extends MIDlet implements CommandListener, Runnable { public static final UUID SERVICIO_CHAT = new UUID(0x2343); private Command comenzar; private Form formulario; private Thread hilo; public void startApp() { thread = new Thread(this); comenzar = new Command("Comenzar", Command.ITEM, 1); formulario = new Form("Ejemplo servidor Bluetooth"); formulario.addCommand(comenzar); formulario.setCommandListener(this); Display.getDisplay(this).setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == comenzar) { hilo.start(); } } public void run() { try { LocalDevice localDevice = LocalDevice.getLocalDevice(); if(!localDevice.setDiscoverable(DiscoveryAgent.GIAC)) { Display.getDisplay(this).setCurrent(new Alert("Existe servicio B")); } StringBuffer url = new StringBuffer("btspp://localhost:"); url.append(SERVICIO_CHAT.toString()); url.append(";name=Servicio chat;authorize=true"); StreamConnectionNotifier notifier = (StreamConnectionNotifier)Connector.open(url.toString()); formulario.append("Servidor en marcha..."); StreamConnection connection = null; DataInputStream in = null; DataOutputStream out = null; while(true) { try { connection = notifier.acceptAndOpen(); in = connection.openDataInputStream(); out = connection.openDataOutputStream(); out.writeUTF("Servidor: HOLA MUNDO"); out.flush(); String s = in.readUTF(); System.out.println("Cliente dice"+s); Enciclopedia Conociendo
341
Autor: Luis Felipe Wanumen Silva System.out.println(s); } catch(IOException e) { e.printStackTrace(); } finally { try { if(in != null) in.close(); if(out != null) out.close(); if(connection != null) connection.close(); } catch(IOException e) { } }// Cierra finally } // Cierra while } catch(IOException e) { e.printStackTrace(); Display.getDisplay(this).setCurrent(new Alert("Error: "+e)); } // Cierra catch } // Cierra run } // Cierra class ServidorB
342
Enciclopedia Conociendo
343
de los anteriores metodos un programador le puede colocar codigo que quiera a cada uno de ellos, sin embargo para que tenga sentido una aplicacin bluetooth es bueno colocar codigo en el metodo deviceDiscovered el cua se invoca cuando un dispositivo bluetooth es encontrado, en nuestro caso colocamos codigo en dicho metodo que se encargue de obtener la direccion remota de dicho dispositivo: String address = remoteDevice.getBluetoothAddress(); String friendlyName = null; try { friendlyName = remoteDevice.getFriendlyName(true); } catch(IOException e) { } y luego de invocar el metodo searchServices aplicado sobre el agente de descubrimiento discoveryAgent, de tal forma que automticamente se inicie el proceso de busqueda de servicios sobre este dispositivo bluetooth, igualmente se guarda en un vector el identificador de estos servicios: int transId = discoveryAgent.searchServices(ATRIBUTOS,SERVICIOS, remoteDevice, this); System.out.println("Comenzada busqueda de serivicios en: "+device+"; "+transId); busquedas.addElement(new Integer(transId)); El otro metodo que vamos a desarrollar es el metodo servicesDiscovered que es invocado automticamente por bluetooth cuando se encuentran servicios, obviamente debido a que en algun momento se invoco el metodo searchServices sobre un agente para lograr que este automticamente ejecute el metodo servicesDiscovered. En nuestro caso el metodo servicesDiscovered obtiene la direccion del servicio ubicado en el dispositivo previamente encontrado para crear un objeto conecction de tal suerte que con este se pueda hacer una manipulacin de los flujos de entrada y de salida al estilo sockets por medio de objetos tipo DataInputStream para recibir lo que el servidor envia y de objetos tipo DataOutputStream para enviarle al servidor mensajes. Nuestro metodo servicesDiscovered tiene el siguiente codigo: public void servicesDiscovered(int transID,ServiceRecord[] servRecord) { ServiceRecord service = null; for(int i=0; i<servRecord.length; i++){ service = servRecord[i]; String url = service.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); StreamConnection connection = null; DataInputStream in = null; DataOutputStream out = null; Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva try { connection =(StreamConnection) Connector.open(url); in = connection.openDataInputStream(); out = connection.openDataOutputStream(); out.writeUTF("saludos desde el cliente!"); out.flush(); String s = in.readUTF(); texto.setString(s); Display.getDisplay(this).setCurrent(texto); } catch(IOException e) { e.printStackTrace(); } finally { try { if(in != null) in.close(); if(out != null) out.close(); if(connection != null) connection.close(); } catch(IOException e) { } } // Cierra finally } // Cierra for } // Cierra void servicesDiscovered Recordemos que nuestro ejercicio no implementa codigo en los metodos serviceSearchCompleted inquiryCompleted con lo cual el codigo fuente para estos metodos toma la apariencia siguiente: public void serviceSearchCompleted(int transID, int respCode) { } // Cierra void serviceSearchCompleted public void inquiryCompleted(int discType) { } // Cierra inquiryCompleted Para no ir tan lejos, a continuacin se muestra el codigo completo de nuestro ciente Bluetooth:
344
import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.*; import javax.bluetooth.*; import java.io.*; import java.util.*; import javax.microedition.io.*; public class ClienteB extends MIDlet implements CommandListener, DiscoveryListener { public static final UUID SERVICIO_CHAT = new UUID(0x2343); public static final UUID[] SERVICIOS = new UUID[]{ SERVICIO_CHAT }; public static final int[] ATRIBUTOS = null; Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva private private private private private private Command comenzar; TextBox texto; Form principal; Form busqueda; Vector busquedas; DiscoveryAgent discoveryAgent;
345
public void startApp() { busquedas = new Vector(); principal = new Form("Ejemplo cliente SPP"); texto = new TextBox("El servidor te dice...","", 50, TextField.UNEDITABLE); comenzar = new Command("Buscar", Command.ITEM, 1); // cancelar = new Command("Cancelar", Command.ITEM, 1); busqueda = new Form("Busqueda de servicio"); busqueda.append(new Gauge("Buscando servicio...",false, Gauge.INDEFINITE,Gauge.CONTINUOUS_RUNNING)); // busqueda.addCommand(cancelar); busqueda.setCommandListener(this); principal.addCommand(comenzar); principal.setCommandListener(this); LocalDevice localDevice = null; try { localDevice = LocalDevice.getLocalDevice(); localDevice.setDiscoverable(DiscoveryAgent.GIAC); discoveryAgent = localDevice.getDiscoveryAgent(); Display.getDisplay(this).setCurrent(principal); } catch(Exception e) { e.printStackTrace(); Alert alert = new Alert("Error","No se puede hacer uso de Bluetooth",null, AlertType.ERROR); Display.getDisplay(this).setCurrent(alert); } } // Cierra void startApp public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == comenzar) { comenzar(); } else /* if( c == cancelar)*/ { // cancelar(); } } // Cierra void void commandAction private void comenzar() { try { Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this); Display.getDisplay(this).setCurrent(busqueda); } catch(BluetoothStateException e) { e.printStackTrace(); Alert alert = new Alert("Error","No se pudo comenzar la busqueda",null, AlertType.ERROR); Display.getDisplay(this).setCurrent(alert); } } // Cierra void comenzar() //metodos de la interfaz DiscoveryListener public void deviceDiscovered(RemoteDevice remoteDevice,DeviceClass deviceClass) { String address = remoteDevice.getBluetoothAddress(); String friendlyName = null; try { friendlyName = remoteDevice.getFriendlyName(true); } catch(IOException e) { } String device = null; if(friendlyName == null) { device = address; } else { device = friendlyName + " ("+address+")"; } // Cierra else try { int transId = discoveryAgent.searchServices(ATRIBUTOS,SERVICIOS, remoteDevice, this); System.out.println("Comenzada busqueda de serivicios en: "+device+"; "+transId); busquedas.addElement(new Integer(transId)); } catch(BluetoothStateException e) { e.printStackTrace(); System.err.println("No se pudo comenzar la busqueda"); } } // Cierra deviceDiscovered public void inquiryCompleted(int discType) { } // Cierra inquiryCompleted public void servicesDiscovered(int transID,ServiceRecord[] servRecord) { ServiceRecord service = null; for(int i=0; i<servRecord.length; i++){ service = servRecord[i]; String url = service.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); Enciclopedia Conociendo
346
Autor: Luis Felipe Wanumen Silva StreamConnection connection = null; DataInputStream in = null; DataOutputStream out = null; try { connection =(StreamConnection) Connector.open(url); in = connection.openDataInputStream(); out = connection.openDataOutputStream(); out.writeUTF("saludos desde el cliente!"); out.flush(); String s = in.readUTF(); texto.setString(s); Display.getDisplay(this).setCurrent(texto); } catch(IOException e) { e.printStackTrace(); } finally { try { if(in != null) in.close(); if(out != null) out.close(); if(connection != null) connection.close(); } catch(IOException e) { } } // Cierra finally } // Cierra for } // Cierra void servicesDiscovered public void serviceSearchCompleted(int transID, int respCode) { } // Cierra void serviceSearchCompleted } // Cierra ClienteB
347
Enciclopedia Conociendo
348
Enciclopedia Conociendo
349
El problema del anterior archivo es que no se puede mostrar dicho archivo desde programas tipo Applet y en primera instancia el resultado de la ejecucin del anterior programa es similar al siguiente:
Existe una manera para lograr que se pueda desde un Applet se puedan ejecutar acciones de este tipo como de lectura de archivos, la forma es generar un certificado para el applet y por ultimo firmar el applet. Para generar el certificado usamos la instruccin: C:\Progra~1\Java\jdk1.6.0\bin\keytool -genkey -alias aliacin -validity 120 v En donde aliacin es el nombre del alias del certificado y 120 significa el numero de dias que sera valido dicho certificado. Nos pregunta la contrasea del almacen de claves:
Enciclopedia Conociendo
350
En este caso colocamos la palabra clave, con lo cual observamos que se produce el siguiente error:
Dado que la contrasea es demasiado corta. Esto simplemente se mostro con el fin de ir comprobando que realmente la clave no puede ser tan corta. Vamos pues a colocar la clave 123456:
Enciclopedia Conociendo
351
Vemos pues que se nos solicita volver a digitar la clave, procedemos pues a volverla a digitar. A continuacin nos pregunta nuestro nombre y nuestro apellido colocaremos pues Luis Wanumen tal como se muestra a continuacin:
Seguidamente colocaremos el nombre de nuestra unidad de organizacin, en este caso colocaremos la palabra Universidad tal como se muestra en el siguiente grafico:
Enciclopedia Conociendo
352
En el nombre de la organizacin colocaremos la palabra Distrital tal como indica la siguiente figura:
Luego nos pide el nombre de la ciudad o localidad, en nuestro caso colocaremos Bogota tal como se muestra en el siguiente pantallaza:
Enciclopedia Conociendo
353
A la pregunta estado o provincia, colocaremos Colombia y en el codigo de pais de dos letras colocaremos co tal como se muestra en el siguiente grafico:
Observamos pues que una vez digitada toda esta informacin se nos solicita confirmar todos estos datos, esta parte es importante pues nos sirve para hacer una ultima verificacin de la informacin que usamos en la creacin del certificado. Observemos por simple curiosidad que pasaria si le colocasemos la palabra yes:
Enciclopedia Conociendo
354
Vemos que vuelve a solicitar los datos, esto sucede porque la configuracin de la maquina virtual esta en espaol con lo cual debemos contestar en espaol tal como se muestra a continuacin:
En este punto es importante notar que el par de claves se generan usando el algoritmo DSA de 1.024 bits. Se solicita entonces la contrasea clave para aliacin, en este caso se recomienda que sea la misma que la del almacen de claves y esto se logra presionando la tecla ENTER, Con todo esto se ha generado el certificado para el applet, tal como corrobora el pantallaza siguiente:
Enciclopedia Conociendo
355
Ahora llego el momento de asociar el applet con el certificado que acabamos de expedir. A este proceso se le conoce con el nombre de firmar el applet, pero hacer que dicha firma quede asociada al mencionado certificado se logra si se conoce la contrasea del almacen de claves. El proceso de firmado del applet comienza con el siguiente comando: C:\Progra~1\Java\jdk1.6.0\bin\jarsigner MyApp.jar aliacin verbose En donde nos solicita la clave del almacen de claves identificado con el alias aliacin, tal como se muestra a continuacin:
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva Y a pesar de haberle colocado bien la clave, nos genera el siguiente error:
356
El error se presente debido a que se tiene que modificar el archivo MyApp.jar y esta siendo usado por el navegador. Incluso para garantizar que funcione a veces se hace necesario cerrar el navegador para que no exista aplicacin alguna que este asociada al archivo MyApp.jar. Esto fue lo que realmente se hizo para que funcionara este ejercicio.
Una vez se ha firmado el applet se tiene claro que el certificado expira en seis meses y esto se muestra mediante un Warning. Una vez se ha firmado el applet, se puede ejecutar desde el navegador, tal como se muestra en la siguiente figura: Enciclopedia Conociendo Curso de Jsp y Servlets
357
Vemos pues que al momento de cargar el applet aparece un aviso de advertencia que se puede ver en mas detalle como se muestra a continuacin:
Enciclopedia Conociendo
358
Esto demuestra que la firma digital ha sido creada, pero lo que aparece no es un error, es simplemente que el contenido esta asociado con un almacen de certificado que no es de confianza pero que si es aprobado por el cliente permitiria la ejecucin de la accion de ver el contenido de un archivo. En este momento y antes de continuar vamos a crear un archivo llamado a.txt con el siguiente contenido:
Para el caso de nuestro ejercicio vamos indicarle al navegador que confiaremos siempre en el contenido del editor Luis Wanumen:
Enciclopedia Conociendo
Autor: Luis Felipe Wanumen Silva Esto se logra sealando en la opcion mencionada tal como muestra la figura anterior. De otra parte ahora hacemos clic sobre el boton con el rotulo Ejecutar. En este momento el navegador puede demorarse un poco debido a que esta validando las acciones que realiza el applet.
359
Enciclopedia Conociendo
360
Bueno, realmente la primera vez que se ejecuto esto no funciono y lo que pasaba era que tocaba pasar los archivos .class a otra carpeta para que el navegador no los tomara y asegurarnos que tomar nicamente el jar que haba sido firmado. La verdad esto no tiene mucha lgica pero en forma real fue algo que se presento cuando se ejecuto este ejercicio y algo que soluciono el problema para lograr que el Applet leyera el archivo.
Enciclopedia Conociendo
361
22.2. REQUERIMIENTOS
Un entorno de desarrollo que soporte servicios web Kit para desarrolladores que proporciona google. Una clave para las APIs de google.
362
y hacer clic sobre el boton Generar Clave de API En nuestro caso google genero la siguiente clave: ABQIAAAAJrGl_mJsgRhksSed5PPrNxT2yXp_ZAY8_ufC3CFXhHIE1NvwkxQH0EuEF7PLIMnfq3z 0SbEz4z__ow
Enciclopedia Conociendo
363
Enciclopedia Conociendo
364
EL PARCIAL ES UN SOFTWARE DOCUMENTADO, PERO EN REALIDAD ESTO ES UN REQUISITO PARA ENTRAR AL PARCIAL, YA QUE EL PROGRAMA ES SIMPLEMENTE ESO, UN PROGRAMA. El parcial es la sustentacin del programa. DESCRIPCION DEL PROGRAMA El programa debe manejar un servidor que sea capaz de pedir solicitudes de varios clientes, de la siguiente forma: Login Crear Usuario Enviar Mensaje Cambiar nombre Usuario Salir
El foro funciona de la siguiente manera: En cliente debe crear un usuario antes de poder enviar un mensaje. El servidor valida al usuario basado en el nombre de usuario que halla llegado. Si dos usuarios tienen el mismo nombre, el servidor no admite en el foro al segundo cliente que tenga un nombre repetido. Un usuario puede cambiar su nombre de usuario y este cambio debe reflejarse en cada uno de los demas clientes. El motor de BD cualquiera. Interfaz com Swing, Awt, Web o como quiera La condicion Lenguaje JAVA. Puede funcionar en Windows o en Linux. Enciclopedia Conociendo Curso de Jsp y Servlets
Autor: Luis Felipe Wanumen Silva Sustentacin en grupos, pero nota individual. Grupos MAXIMO 3 Fecha 12 de marzo. Celular 315 832 72 69
365
ANDREA SANCHEZ, ANGELICA SANCHEZ Y DANIEL GOMEZ Ventajas de hacer una web semantica con JENA y Protege
Enciclopedia Conociendo Curso de Jsp y Servlets
366
Desventajas de hacer una web semantica con Protege. Ejemplos buenos bajados de Internet. Documentos de Soporte. Aportes
CAMILO ANDRES CHAVEZ LAURA VELASCO Y ANGELA VARGAS Que se esta haciendo actualmente para ponerle seguridad a los servicios Web.
Enciclopedia Conociendo
367
Enciclopedia Conociendo
368
FERNANDO AGUDELO YEPES Opcion 1 Servicios web con Java Manual Paso a paso Ejemplos Opcion 2 Grilla computacional con Java
369
Hacer un chat con tecnologa RMI que tenga en cuenta los mensajes perdidos cuando cualquier cliente se desconecte. OTRAS PROPUESTAS. Hacer programas que creen archivos XML usando DOM, permitiendo anadir, buscar y ordenar elementos del archivo XML. Hacer programas que creen archivos XML usando SAX, permitiendo anadir, buscar y ordenar elementos del archivo XML. Hacer programas que creen archivos XML usando JDOM, permitiendo anadir, buscar y ordenar elementos del archivo XML.
370
LES ACONSEJO ESUDIAR Y ACCEDER A LOS SIGUIENTES ENLACES(Especialmente a Heidy y Lorena que van a trabajar monitoreo desde un movil) a. Para comprender el modelo de capas JMX http://es.wikipedia.org/wiki/Java_Management_Extensions b. DE AQUI SE PUEDE BAJAR SIGAR http://sourceforge.net/projects/sigar/files/sigar/1.6/hyperic-sigar-1.6.3.zip/download https://sourceforge.net/project/showfiles.php?group_id=172552 c. UN EJEMPLO USANDO SIGAR http://casidiablo.net/descargar/Informacion+Sistema+Java d. Estudiar las especificaciones JSR para JMX que son: JSR 255 (JMX 2.0) JSR 160 JMX Remote API JSR 3 (JMX 1.0, 1.1, y 1.2) e. Un Link para comprender que es JDMK http://es.wikipedia.org/wiki/JDMK http://catalogs.sun.com/is-bin/INTERSHOP.enfinity/WFS/Sun_Catalogue-Sun_Catalogue_MXSite/es_ES/-/USD/ViewCatalogBrowse;pgid=Q2ye6_Ocx8nOZgiKCJkpiAe00000iMyu1CV5;sid=rYOP3irSQqWv3mG87UspbrJTxfq 5LnIP_hvXA3lKxfq5Lg==?CatalogCategoryID=nopIBe.dDNsAAAEUL045G_c2 f. API para trabajar SNMP con Java http://www.snmp4j.org/
Enciclopedia Conociendo
371
Autor: Luis Felipe Wanumen Silva Sun Microsystem Cay s. Hortstmann / Gary Cornell Prentice Hall Seguridad en Java Edicion Especial Jamie Jaworski Paul J.Perrone. Prentice Hall. Como programar en Java Deitel y Deitel Prentice Hall JavaServer Pages Manual de Usuario y Tutorial Agustin Froufe AlfaOmega @RA-MA. 2002 Desarrollo de Juegos con J2ME AlfaOmega @RA-MA. Manuel J. Prieto. Manual de Usuario. J2EE Keogh Mc Graw Hill
372
2.
3. 4. 5.
Enciclopedia Conociendo
373
"Java Network Programming" , Elliotte Rusty Harold, O'Reilly, 1997. Referencia detallada sobre programacin en redes, muy recomendables los captulos de Sockets, URLs y Manejadores de Contenido
4. 5. 6.
Enciclopedia Conociendo
374
Enciclopedia Conociendo
375
Enciclopedia Conociendo
376
TABLA DE CONTENIDO
1. CONCEPTOS BASICOS DE SERVLETS............................................................................................2 1.1. LOS COMPONENTES NECESARIOS..........................................................................................2 2. SERVLETS SENCILLOS CON CONEXIN A BASES DE DATOS.................................................3 2.1. SERVLET QUE MUESTRA DATOS DE UNA TABLA..............................................................3 2.2. SERVLET QUE INSERTA DATOS EN BASE DE DATOS........................................................5 2.3. PAGINACION CON SERVLETS................................................................................................12 2.4. BUSCAR UN REGISTRO EN SQL SERVER 2000 Y USANDO SERVLETS..........................20 2.5. PAGINACION CON SIGUIENTE Y ANTERIOR......................................................................26 2.6. SELECCIN DE DATOS DE ORACLE 10G..............................................................................33 3. CONCEPTOS BASICOS DE JSP........................................................................................................37 3.1. CICLO DE VIDA DE PAGINA JSP.............................................................................................37 3.2. ES POSIBLE QUE PAGINAS JSP CONTENGAN CODIGO NO JSP.......................................37 3.3. COMENTARIOS EN PAGINAS JSP...........................................................................................38 3.4. DECLARANDO VARIABLES EN JSP Y USO DE EXPRESIONES........................................38 3.5. UNA FORMA DE IMPRIMIR ELEMENTOS EN JSP...............................................................39 3.6. LA DIRECTIVA INCLUDE.........................................................................................................41 3.7. CUIDADOS CON LA DIRECTIVA INCLUDE..........................................................................42 3.8. LA DIRECTIVA PAGE IMPORT................................................................................................45 3.9. UN TIP SOBRE LAS IMPORTACIONES...................................................................................47 3.10. UN TIP SOBRE LAS DECLARACIONES................................................................................48 4. PAGINACIN DE RESULTADOS CON JSP....................................................................................50 4.1. RECONOCER QUE PARAMETRO SE ENVIA EN PAGINAS RECURSIVAS.......................50 4.2. RECONOCER CUANTAS PAGINAS SON NECESARIAS .....................................................52 4.3. IMPRIMIR LOS HIPERENLACES NECESARIOS DE ACUERDO CON EL NUMERO DE PAGINAS DE USUARIO....................................................................................................................53 4.4. COLOCAR HIPERENLACE ANTERIOR...................................................................................54 4.5. COLOCAR HIPERENLACE SIGUIENTE..................................................................................56 4.6. DEPENDIENDO LA PAGINA ACTUAL, SE DEBE CALCULAR EL RANGO DE REGISTROS A MOSTRAR................................................................................................................58 4.7. CORREGIR EL NUMERO DE REGISTROS QUE APARECEN EN LA ULTIMA PAGINA. 63 4.8. ARMAR LA CADENA DE CONSULTA Y ENSAMBLAR LA APLICACION.......................66 4.9. HACER QUE EL NUMERO DE REGISTROS SEA DINAMICO.............................................67 5. ETIQUETAS JSP.................................................................................................................................71 5.1. PRIMER EJERCICIO DE ETIQUETAS JSP...............................................................................71 5.2. ERROR COMN CON EL USO DE TAGS................................................................................73 5.3. UN TAG QUE CONSULTA DATOS...........................................................................................75 6. FORMA DE HACER TAGS CON NETBEANS 6.5.1........................................................................81 6.1. CREAR LA LIBRERA DE ETIQUETAS...................................................................................81 6.2. CREAMOS LA ETIQUETA PROPIAMENTE DICHA..............................................................82 6.3. CREAMOS EL BEAN..................................................................................................................82 6.4. DESDE UNA JSP USAMOS EL TAG.........................................................................................83 6.5. CREAMOS LA BASE DE DATOS..............................................................................................84 6.6. INGRESAMOS ALGUNOS DATOS...........................................................................................84 6.7. EJECUTAMOS LA APLICACION..............................................................................................85 6.8. TALLER PROPUESTO SOBRE TAGS JSP................................................................................85 7. CREANDO SENCILLA APLICACIN WEB NETBEANS 3 CAPAS.............................................86 7.1. PASO 1: CREAR LA BASE DE DATOS.....................................................................................86 Enciclopedia Conociendo Curso de Jsp y Servlets
377
7.2. PASO 2: CREAR EL ORIGEN DE DATOS...............................................................................89 7.3. PASO 3: CREACION DE UN PROYECTO WEB CON NETBEANS.......................................92 7.4. PASO 4: CREACION DEL PAQUETE QUE TENDRA LA LOGICA Y EL ACCESO A DATOS.................................................................................................................................................97 7.5. PASO 5: CREACION DE LA VISTA........................................................................................103 7.6. PASO 6: INGRESANDO CODIGO EN EL MODELO.............................................................105 7.7. PASO 7: INGRESANDO CODIGO EN EL CONTROLADOR................................................107 7.8. PASO 8: INGRESANDO CODIGO EN LA VISTA..................................................................109 7.9. PASO 9: ENSAMBLE Y DESPLIEGUE DE LA APLICACION..............................................110 7.10. PASO 10: EJECUCION DE LA APLICACIN......................................................................112 8. MANIPULACION DE COOKIES Y SESIONES.............................................................................114 8.1. CREACION DE UNA COOKIE DESDE UN SERVLET..........................................................114 8.2. CREACION DE UNA SESSION DESDE UNA JSP.................................................................115 9. ELABORACION DE UN CHAT POR PASOS.................................................................................118 9.1. PRIMEROS PASOS....................................................................................................................118 9.2. UN EJEMPLO DE UN CLIENTE Y UN SERVIDOR...............................................................119 9.3. EL METODO ACCEPT DE SERVERSOCKET........................................................................127 9.4. SEGUNDA MEJORA AL PROGRAMA ANTERIOR..............................................................128 9.5. MEJORANDO EL PROGRAMA ANTERIOR COLOCANDOLE UNAS BELLAS INTERFACES GRAFICAS...............................................................................................................130 9.6. EL SERVIDOR CREA AADE A LA LISTA CADA VEZ QUE LLEGA UN CLIENTE.....133 9.7. QUE ES UN HILO......................................................................................................................137 9.8 CHAT PUBLICO USANDO HILOS...........................................................................................138 10. PROGRAMA SIN MODELAR NO ES PROGRAMAR.................................................................144 10.1. IMPORTANCIA DEL DIAGRAMA DE ESTADOS EN UN ENVIO DE INFORMACION MINICHAT........................................................................................................................................144 10.1.1. DESCRIPCION......................................................................................................................144 10.1.2. EL LADO DEL SERVIDOR ES:...........................................................................................144 10.1.3. EL LADO DEL CLIENTE ES:..............................................................................................148 10.2. IMPORTANCIA DEL DIAGRAMA DE CLASES EN EL MODELAMIENTO DE UN PROGRAMA DE UN PIRATA.........................................................................................................151 10.2.1. PLANTEAMIENTO DEL ENUNCIADO.............................................................................151 10.2. ESTABLECIMIENTO DE FRASES IMPORTANTES...........................................................151 10.2.2. ESTABLECIMIENDO DE CLASES.....................................................................................152 10.2.3. PROGRAMA EN JAVA........................................................................................................153 10.2.4. EJECUCIN DEL PROGRAMA:.........................................................................................158 10.3. IMPORTANCIA DEL DIAGRAMA DE CLASES EN EL MODELAMIENTO DE UN PROGRAMA DE UN AVION...........................................................................................................161 10.3.1. DIAGRAMA DE CLASE......................................................................................................161 10.3.2. EXPLICACIN DE LA IMPLEMENTACIN....................................................................162 10.3.3. EJECUCIN DEL PROGRAMA..........................................................................................170 11. ENVIO Y RECEPCION DE CORREO ELECTRONICO...............................................................173 11.1. ENVIO DE CORREO DESDE UNA INTRANET...................................................................173 11.2. ENVIO DE CORREO CON ARCHIVO ADJUNTO...............................................................174 11.3. CONECTAR A SERVIDOR DE CORREO USANDO SOCKETS ........................................176 11.4. ENVIANDO MENSAJES DE CORREO USANDO SOCKETS.............................................177 12. ENVIO DE ARCHIVOS POR FTP..................................................................................................179 12.1. CONECTARSE A SERVIDOR FTP........................................................................................179 12.2. ENVIAR ARCHIVOS A SERVIDOR FTP..............................................................................180 12.3. CONECCION SERVIDOR FTP USANDO SOCKETS...........................................................181 13. TRABAJANDO CON RMI..............................................................................................................185 13.1. DESCRIPCION DE EJERCICIO..............................................................................................185 13.2. PRIMERO CREAMOS Y COMPILAMOS LA CLASE INTERFACE ..................................185 Enciclopedia Conociendo Curso de Jsp y Servlets
378
13.3. CREAMOS Y COMPILAMOS EL OBJETO REMOTO QUE SE VA A COMPARTIR.......186 13.4. CREAMOS LA APLICACIN DEL LADO DEL SERVIDOR..............................................187 13.5. REGISTRAR EL OBJETO REMOTO......................................................................................188 13.6. SUBIR EL SERVIDOR RMI....................................................................................................188 13.7. COLOCAMOS LA APLICACIN QUE HICIMOS EN EL SERVIDOR RMI......................189 13.8. INVOCACION DEL CLIENTE................................................................................................189 13.9. SCRIPT PARA EJECUTAR EL CLIENTE..............................................................................189 14. BEAN Y JAVA BEAN.....................................................................................................................191 14.1. ARQUITECTURA DE LOS JAVA BEAN..............................................................................191 14.2. BEAN TIPO MESSAGE CON JAVA......................................................................................195 14.3. CREACION DE UN BEAN DE ENTIDAD CON NETBEANS Y ORACLE 10G EXPRESS ............................................................................................................................................................208 15. EJERCICIO DE WEB SERVICE.....................................................................................................234 15.1. CONSEGUIR EL SOFTWARE ANTES DE TRABAJAR......................................................234 15.2. CONFIGURACION PREVIA DEL SERVIDOR.....................................................................235 15.3. INSTALACION DEL SOFTWARE EN EL LADO DEL SERVIDOR...................................238 15.4. PROBAMOS LA CONFIGURACION DEL LADO DEL SERVIDOR..................................248 15.5. ALGUNOS PROBLEMAS QUE SE PRESENTARON FUERON:.........................................258 15.6. MONTAJE DE UN EJERCICIO SENCILLO..........................................................................264 15.7. PROBANDO EL LADO DEL CLIENTE.................................................................................266 15.8. MANUAL DE INSTALACIN:...............................................................................................279 15.9. CARACTERSTICAS TCNICAS DONDE EJECUTO EL CLIENTE..................................287 16. FRAMEWORKS PARA REALIZAR PRUEBAS...........................................................................288 16.1. FUNCIONAMIENTO DE JUNIT.............................................................................................288 16.2. CONSTRUCCION DE LA CLASE QUE VAMOS A PROBAR............................................289 16.3. CONSTRUCCION DE CASO DE PRUEBA PARA CLASE LISTA......................................292 16.4. ELABORACION DEL PROGRAMA QUE EJECUTA LA PRUEBA....................................295 16.5. EJECUCION DEL TESTRUNNER..........................................................................................295 17. INTRODUCCION A LAS APLICACIONES MOVILES...............................................................302 17.1. PINTAR MEDIA PANTALLA CON UN LIENZO.................................................................302 17.2. COLOCAR DOS LIENZOS......................................................................................................307 17.3. PINTAR LA BANDERA DE COLOMBIA..............................................................................309 17.4. COLOCAR UNA FORMA EN LA PANTALLA.....................................................................312 17.5. AADIR UN STRING A UNA FORMA.................................................................................315 17.6. UN PRIMER MENU CON EVENTOS....................................................................................317 18. EJEMPLO DE SERVICIO WEB MOVIL.......................................................................................325 18.1. CONECTARSE A UN SERVIDOR WEB DESDE UN MOVIL.............................................325 19. EJEMPLO DE SERVICIO WEB MOVIL.......................................................................................327 19.1. CREACION DE LA APLICACIN MOVIL...........................................................................327 19.2. MONTAJE EN EL SERVIDOR DE SERVICIOS WEB.........................................................330 19.3. EJECUCION DEL SERVICIO.................................................................................................332 20. TECNOLOGIA BLUETOOTH........................................................................................................336 20.1. MOSTRANDO ESTADO DE UN DISPOSITIVO BLUETOOTH..........................................336 20.2. CREACION DEL SERVIDOR BLUETOOTH .......................................................................339 20.3. CREACION DEL CLIENTE BLUETOOTH ...........................................................................342 21. SEGURIDAD EN JAVA..................................................................................................................348 21.1. APPLET QUE LEE UN ARCHIVO LOCAL...........................................................................348 22. PROGRAMACION CON GOOGLE...............................................................................................361 22.1. DEFINICION DE APIS DE GOOGLE: ...................................................................................361 22.2. REQUERIMIENTOS................................................................................................................361 22.3. ALGUNAS APIS DE GOOGLE...............................................................................................361 22.4. OBTENER LA CLAVE DEL API DE GOOGLE MAPS........................................................361 22.5. COLOCAR LA ALTITUD Y LA LATITUD...........................................................................362 Enciclopedia Conociendo Curso de Jsp y Servlets
379
22.6. ALGUNAS COSAS CURIOSAS DE GOOGLE......................................................................362 23. INVESTIGACIONES PROPUESTAS PARA LOS ESTUDIANTES DE JAVA AVANZADO...364 23.1. PROPUESTA DE PARCIAL PRIMERO.................................................................................364 23.2. UNA PRIMERA PROPUESTA................................................................................................365 23.3. PROPUESTAS PARA EL SEMESTRE 2007 III.....................................................................368 23.4. PROPUESTAS PARA EL SEMESTRE 2008 I........................................................................368 23.5. PROPUESTAS PARA EL PRIMER SEMESTRE 2010 I........................................................369 24. BIBLIOGRAFA E INFOGRAFA..................................................................................................371 24.1. BIBLIOGRAFIA FACIL DE CONSEGUIR EN COLOMBIA SOBRE JAVA.......................371 24.2. REFERENCIAS DE JAVA.......................................................................................................372 24.3. REFERENCIAS DE JAVA-CORBA-RMI...............................................................................373 TABLA DE CONTENIDO....................................................................................................................376
Enciclopedia Conociendo