Esta publicación es la continuación de la parte 1, la cual puedes encontrarla en el siguiente enlace: https://algoritmosyalgomas.com/login-java-web-usuario-password-conexion-base-datos-mysql-n-capas/
Como ya te había mencionado en la entrada anterior, nuestro objetivo será tener una aplicación java web estructurada en varias capas. Para ello, vamos a crear la siguiente estructura de paquetes y carpetas en nuestro proyecto web “JavaWeb”. Cada paquete representará una capa (aunque no siempre tiene que ser así).
Hasta el post anterior, en nuestro proyecto teníamos creados los paquetes conexion y test. Para este post deberán crear los paquetes restantes: controlador, entidad y modelo.
En total tendremos los siguientes paquetes (se añade una breve descripción del uso que se le dará):
- conexion: Paquete que contiene la clase reutilizable Conexion.java la cual tiene la lógica de conexión entre la aplicación Java y la base de datos MySQL.
- controlador: Paquete que contendrá todos los Servlets, los cuales son clases Java que permiten recibir y responder peticiones HTTP.
- entidad: Paquete que contendrá todas las clases que representarán a cada tabla de la base de datos.
- modelo: Paquete que contendrá todas las clases de tipo model, las cuales se encargarán de interactuar con las tablas de la base de datos.
- test: Es un paquete donde tendremos algunas clases de prueba, será borrada al final.
Dentro de la carpeta WebContent debemos crear las siguientes carpetas:
- css: Más adelante Incluiremos algunos archivos de estilos css.
- js: Posteriormente Incluiremos algunos archivos javascript para realizar ciertas validaciones y darle más interactividad a las páginas en caso se requiera.
- img: En esta carpeta guardaremos algunas imágenes.
Recuerda que si no tienes la carpeta WebContent, en su lugar tendrás la estructura de carpetas src/main/webapp.
Creación de la Entidad Usuario
Creamos la clase Usuario.java dentro del paquete entidad con el código que se muestra a continuación.
Nota que los atributos de la clase Usuario.java están coincidiendo con las columnas de la tabla usuario de la base de datos. Esto lo hacemos así porque allí es donde se van a recuperar los datos de la tabla usuario.
A la columna idUsuario (cuyo tipo de dato es INT) de la tabla usuario le corresponde el atributo idUsuario de tipo int en la clase Usuario.
A la columna nombre (cuyo tipo de dato es VARCHAR) de la tabla usuario le corresponde el atributo nombre de tipo String en la clase Usuario.
A la columna clave (cuyo tipo de dato es VARCHAR) de la tabla usuario le corresponde el atributo clave de tipo String en la clase Usuario.
A esto que estamos haciendo se le suele denominar mapeo objecto relacional. Aquí estamos realizando un mapeo manual, sin embargo, ya existen herramientas que realizan este mapeo de forma automática tales como Hibernate, MyBatis, etc. A dichas herramientas se les denomina ORM’s.
Si la aplicación que estamos desarrollando tiene más tablas, lo más común es crear una clase por cada tabla y realizar el mapeo entre columnas y atributos, teniendo en cuenta de manejar un tipo de datos similar.
El tipo INT en SQL se corresponde con el tipo int o Integer en Java.
El tipo VARCHAR, CHAR, etc en SQL se corresponde con String en Java.
Creación del Modelo Usuario
Se creará la clase ModeloUsuario.java dentro del paquete modelo:
Las clases de tipo Model, en general, son las que interactúan con la base de datos ya sea recuperando o guardando datos. Para nuestro proyecto web, la clase ModeloUsuario es una clase que engloba la lógica para interactuar con la tabla usuario de la base de datos. Por lo general, se creará una clase Model por cada tabla de la base de datos.
Dentro de la clase ModeloUsuario hemos definido un método llamado iniciarSesion, el cual espera recibir dos parámetros de tipo String: nombre y clave, y cuyo tipo de retorno es un objeto de la clase Usuario.
En la línea 18 se observa cómo se reutiliza la clase Conexion (del paquete conexion) para obtener la referencia de la conexión [a la base de datos] mediante la invocación del método estático getConexion. Luego, se almacena dicha referencia en una variable cn de tipo Connection.
En la línea 19 se define el String “SELECT U.idUsuario, U.nombre, U.clave FROM usuario U WHERE U.nombre = ? AND U.clave = ?“, la cual es una sentencia SQL de forma parametrizada que permite consultar en la tabla usuario por aquellos registros cuyas columnas nombre y clave coincidan con los valores que se establezcan luego (actualmente los valores tienen signos de interrogación).
Entre las líneas 20 y 22 se hace uso del objeto pstm PreparedStatement para preparar una sentencia parametrizada y se setean los parámetros nombre y clave que vienen como argumento del método iniciarSesion. En la línea 23 se ejecuta el método executeQuery el cual ejecutará la sentencia SQL ya preparada y seteada, el resultado obtenido se asigna a la variable rs de tipo ResultSet.
En la línea 25 a 30 se usa un while para evaluar la variable rs en busca de posibles resultados mediante el método next. En caso haya al menos un resultado, el bucle while se ejecutará una vez y se encapsularán los datos obtenidos de la tabla usuario de las columnas idUsuario, nombre y clave en los correspondientes atributos idUsuario, nombre y clave de un objeto Usuario.
En la línea 52 se retorna la variable usuario, el cual puede ser nulo en caso de que la sentencia SQL no haya obtenido resultados o un objeto Usuario con datos seteados en caso de que la consulta haya sido exitosa.
Entre las 32 a 49 se manejan posibles excepciones mediante el bloque catch y se liberan los recursos dentro del bloque finally (se cierran conexiones abiertas por los objetos rs (ResultSet), pstm (PreparedStatement) y cn (Connection). Se recomienda que se cierren dichas conexiones en el orden inverso en el que fueron abiertas).
Creación del Servlet Usuario
Un Servlet es un componente Java que se ejecuta en un servidor y permite atender peticiones que provienen desde un navegador (cliente), procesarlas y devolver respuestas (generalmente páginas web).
En nuestra aplicación, el servlet Usuario atenderá dos tipos de peticiones que le hagamos:
– iniciar sesión: En esta petición o solicitud o request, le mandaremos como parámetros dos datos: nombre de usuario y clave. El servlet los procesará, consultará a la base de datos reutilizando la clase ModeloUsuario y si existe o no el usuario en la base de datos, armará una respuesta adecuada.
– cerrar sesión: En esta petición, no le mandaremos parámetros de entrada y solo se indicará que elimine la sesión del usuario actual.
Vamos a crear la clase “ServletUsuario”. Para ellos hacemos clic derecho en el paquete controlador, elegimos “New” y luego “Other…”
Nos aparecerá la ventana “New” en la cual buscaremos la opción “Web” y dentro hacemos clic en “Servlet”. Luego damos clic en el botón “Next”.
En la siguiente ventana debemos elegir un nombre para el Servlet. Pondremos para esta ocasión ServletUsuario, posteriormente hacemos clic en Next.
En esta ventana vamos a seleccionar el elemento “/ServletUsuario” de la lista de URL mappings y vamos a dar clic en el botón “Edit…”
En la nueva ventana que se abrirá, le asignaremos el siguiente nombre: “/usuario”. Este nombre se usará para hacer referencia al Servlet desde las páginas JSP. Más adelante veremos el uso de esta característica. Luego damos clic en el botón “OK”
Damos clic en Next.
En la ventana actual nos aseguraremos de desmarcar el checkbox “Constructors from superclass“. Y también desmarcaremos “doPost” y “doGet“, y dejaremos marcado el checkbox “service“, luego damos clic en Finish.
Estos pasos lo estamos haciendo de esta manera para construir un Servlet que sea lo más simple posible.
El IDE se encargará de crearnos el Servlet con las características que seleccionamos durante los pasos previos.
Para programar con mayor comodidad podemos eliminar los comentarios autogenereados. Al final tendremos el código como se muestra a continuación.
Dentro de esta clase ServletUsuario podremos codificar lo siguiente:
El Servlet será la clase Java encargada de recibir las peticiones o solicitudes realizadas por el cliente hacia el servidor y también de enviar las respuestas siguiendo alguna lógica. Toda la información que el cliente mande al servidor en la petición lo hará a través del objeto request (HttpServletRequest). El servlet usará dicho objeto para recuperar la data enviada por el cliente en cada solicitud. El Servlet también recibe un objeto response (clase HttpServletResponse) el cual contiene la respuesta del servlet ante la petición, es decir, toda la información de salida.
Para el servlet ServletUsuario, el objeto request de la petición que viene desde el cliente, trae consigo dos parámetros: nombre y clave. En las líneas 20 y 21 se muestra cómo acceder al objeto request y recuperar los parámetros nombre y clave para luego asignarlos a las variables String del mismo nombre.
En la línea 23 se instancia la clase ModeloUsuario y en la línea 24 se utiliza el modelo creado para poder ejecutar el método iniciarSesion pasándole como argumentos el nombre y clave recibidos desde la petición. El método iniciarSesion retornará un objeto Usuario y lo almacenará en la variable usuario en caso de que exista un registro usuario en la tabla usuario para el usuario/clave dados, o en caso contrario null.
En la línea 26 se examina el valor de la variable usuario declarada en la línea 24. Tendremos dos posibilidades:
- Si el valor de la variable usuario es null:
- Línea 27: Utilizamos el objeto request para setear un atributo llamado mensaje con el string “Error nombre de usuario y/o clave” con la finalidad de recuperarlo y mostrarlo más adelante en caso de que el inicio de sesión falle.
- Línea 28: Redirigimos la petición hacia una página index.jsp (que será creada más adelante) y le volveremos a pasar los objetos request y response con toda la información de entrada y salida que se tiene hasta el momento.
- Si el valor de la variable usuario no es null, es decir, es un objeto:
- Línea 30: Se utiliza el objeto response para responder con una redirección hacia la página principal.jsp. Esto quiere decir, que se realizó correctamente el inicio de sesión.
Creación de las páginas JSP: index.jsp y principal.jsp
Dentro de la carpeta WebContent vamos a crear los archivos JSP index.jsp y principal.jsp. Para ello hacemos clic derecho en la carpeta “WebContent“, elegimos “New” y luego “JSP File”.
OBS: Recordar que si su proyecto no tiene la carpeta “WebContent“, debería tener “src/main/webapp“.
index.jsp
La página index.jsp es la página en donde estará el formulario de inicio de sesión.
Dentro del cuerpo, es decir, entre las etiquetas <body> definimos un formulario mediante la etiqueta <form>, allí definimos los atributos:
- action: usuario, aquí indicamos quién será el encargado de recibir los datos del formulario y de procesar la petición. Por lo tanto, debemos hacer referencia al servlet ServletUsuario que creamos previamente.
- method: post, es el tipo de método de la petición HTTP
Luego básicamente definimos una tabla con 3 filas mediante el uso de las etiquetas table, tr y td para las columnas. Definimos dos cuadros de texto, cuyos atributos name son: “nombre” y “clave“, mediante la etiqueta input.
Un botón de tipo submit para enviar los datos ingresados en el formulario de inicio de sesión hacia el servidor.
Hay que tener presente que los atributos name de los input text del formulario del archivo index.jsp deben coincidir con los nombres de los parámetros desde donde se recupera la información en el servlet ServletUsuario tal y como se observa en la siguiente imagen:
principal.jsp
La página principal.jsp será la primera página a la que nos redireccione el sistema una vez que nos hayamos logeado correctamente.
Prueba de la aplicación web
Vamos a ejecutar la aplicación web para verla en funcionamiento. Nos situamos encima del archivo index.jsp y le damos clic derecho. En el menú contextual elegimos la opción Run As y luego damos clic en Run on Server.
Aparecerá una ventana llamada Run On Server, en esta debemos asegurarnos de que se encuentre seleccionada Tomcat v8.5.
Luego damos clic en el botón Finish.
En el editor de código se abrirá una nueva pestaña con un navegador interno en el cual se muestra el formulario html de la página index.jsp.
Vamos a probar la aplicación ingresando las credenciales incorrectas, por ejemplo:
- usuario: jose
- clave: xyz
Luego damos clic en el botón “Iniciar sesión”
Se recargará la página y se nos mostrará el mensaje de error que definimos en el servlet: “Error nombre de usuario y/o clave“.
Ahora vamos a probar ingresando correctamente el nombre de usuario y la clave:
- usuario: jose
- clave: 123
Damos clic en el botón “Iniciar sesión”.
Ahora sí podremos notar que la aplicación nos redirecciona hacia la página correcta, es decir, hacia principal.jsp
Hasta aquí termina la parte 2 de esta entrada. Para ver la continuación puedes entrar a este enlace:
Login en Java web y MySQL N capas (JSP’s y Servlets) Parte 3
La lista completa de entradas relacionadas a esta son las siguientes:
Parte 1: Login en Java web y MySQL – N capas (JSP’s y Servlets) Parte 1 – 4
Parte 2: Login en Java web y MySQL – N capas (JSP’s y Servlets) Parte 2 – 4
Parte 3: Login en Java web y MySQL – N capas (JSP’s y Servlets) Parte 3 – 4
Parte 4: Login en Java web y MySQL – N capas (JSP’s y Servlets) Parte 4 – 4