Login básico con Servlets & AJAX

Pantalla de login

La web ha estado en constante evolución, desde las primeras versiones de HTML, HTTP, se ha estado avanzando poco a poco pero de gran manera hasta tener ahora diversas tecnologías a disposición que simplifican y nos permiten realizar cosas cada vez mejores. Una de las ahora bastamente usadas pero que marcó un nuevo enfoque en el desarrollo web es AJAX (Asynchronous JavaScript And XML).

¿Qué es AJAX?

AJAX es una técnica en el desarrollo web en el cual el cliente mantiene una comunicación asíncrona entre el cliente y el servidor, permitiendo una comunicación real-time entre ambas. Entre sus características tenemos:

  • Realizar cambios parciales en el documento sin recargar la web.
  • Usabilidad e interactividad mucho mejor y más natural.
  • Baja latencia al no recargarse todo el documento y realizar peticiones nuevamente a los recursos.

Herramientas

La estructura de nuestro proyecto será así:

login-ajax-structure

Como nosotros somos prácticos, vamos a desarrollar un login donde se hagan peticiones AJAX a un servlet que se encargará del login. Dentro de WebContent creamos login.html.

login.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>J7EE Chat - Principal</title>
    <link rel="shortcut icon" href="img/logo.png" />
    <link rel="stylesheet" href="css/normalize.css" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" />
    <link rel="stylesheet" href="css/notificator.css" />
    <link rel="stylesheet" href="css/login.css" />
</head>
<body>



<form action="login" method="get" id="login-form">


<header class="header">
            <img src="img/logo.png" />
        </header>




<section class="body">


<section class="input-group">
                <input type="text" name="username" placeholder="Usuario" />
                <input type="password" name="password" placeholder="Contraseña" />
            </section>


            <input type="submit" value="Ingresar" class="btn-login" />
        </section>


    </form>


    


<div class="notificator">
	    <span class="icon">
	        <i class=""></i>
	    </span>
	    <span class="text"></span>
	    <span class="close"><i class="fa fa-close"></i></span>
	</div>


    
    <script src="js/notificator.js"></script>
    <script src="js/login.js"></script>
</body>
</html>

El login es muy parecido al login del post Servlets y JSP – Introducción. Tiene unos pequeños cambios que solo son de maquetado para darle estilo mediante CSS. También vemos que añadimos nuestra notificación, ya veremos para qué.

login.js (WebContent/js)

document.addEventListener('DOMContentLoaded', init);

function init() {
    var notificator = new Notificator(document.querySelector('.notification'));
    var loginForm = document.querySelector('#login-form');

    loginForm.onsubmit = function(e) {
        e.preventDefault(); // previene el submit por defecto
        
        var method = loginForm.getAttribute('action');
        var method = loginForm.getAttribute('method');
        var params = getFormattedParams();
        
        var ajax = new XMLHttpRequest();
        ajax.open('GET', 'login?' + params, true);
        
        ajax.onload = function() {
            if(ajax.status == 200) {
                //window.location = "/home";
            } else {
                showError(ajax.responseText);
            }
        }
        
        ajax.send();
    }
    
    function getFormattedParams() {
        var url = "";
        var username = loginForm.querySelector('input[name=username]').value;
        var password = loginForm.querySelector('input[name=password]').value;
        url += "username=" + username + "&amp;amp;password=" + password;
        
        return url;
    }
    
    function showError(message) {
        notificator.error(message);
    }
}

Todo ocurre dentro de init, que se ejecutará cuando el documento esté totalmente cargado, preveniendo así posibles errores de referencia nula cuando intentemos obtener los elementos HTML (porque el documento aún no ha cargado).

Se crea un objeto Notificator pasándole como referencia el elemento .notification para que haga cambios en él. También se obtiene el formulario mediante su ID y se le añade un listener para evento ‘submit’ al formulario. Dentro del evento, lo primero que hacemos será detener el comportamiento por defecto del evento submit llamando al método preventDefault.

Obtenemos los datos de la petición: el destino, el método y los parámetros. Para los parámetros se hace una concatenación de las parámetros con un identificador para luego concatanerla a la URL destino para una petición GET (‘login?param1=valor1&paramN=valorN’). A continuación viene nuestra petición AJAX.

    1. Se crea un objeto tipo XMLHttpRequest que nos provee de lo necesario para hacer una petición asíncrona al servidor.
    2. Por medio del método open, indicamos: el método, la url y si la llamada será asíncrona o no.
    3. Añadimos un listener al objeto XMLHttpRequest de tipo load. Esta función se ejecutará cuando la pétición termine su carga. Toda petición HTTP tiene códigos de estado los cuales nos sirven para saber el estado de una petición. Algunos de estos son:
      • 200: Petición exitosa terminada.
      • 202: Petición exitosa en curso.
      • 404: Recurso no encontrado.
      • 400: Petición errónea.
  1. Si el código de estado es 200 (ver descripción) hacemos algo, como por ejemplo una redirección a la página de inicio (lo veremos en otro post).
  2. Si el código de estado es 400 (así lo estipularemos en el servlet si las credenciales son erróneas) mostraremos un mensaje en la notificación. Este mensaje será enviado desde el servlet como veremos en un momento.
  3. Enviamos la petición mediante el método send.

Servlet

Nuestro servlet será muy sencillo, solo comprobaremos de manera muy simple las credenciales y si no coinciden enviamos un mensaje de error junto con el código HTTP 400, que indica que es una mala petición 😉

package pe.migasoft.loginajax.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name="LoginServlet", urlPatterns={"/login"}, asyncSupported=true)
public class Login extends HttpServlet {

	private static final long serialVersionUID = -2975613143576849801L;
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
						throws IOException, ServletException {
		
		response.setStatus(HttpServletResponse.SC_OK); // por defecto, enviamos un código 200

		String username = request.getParameter("username");
		String password = request.getParameter("password");
			
		boolean areCredentialsRight = username.length() &amp;gt; 0 &amp;amp;&amp;amp; password.equals("12345");

		if(!areCredentialsRight) {
			response.setContentType("text/plain");
			response.setCharacterEncoding("UTF-8");
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);

			PrintWriter writer = response.getWriter();
			writer.write("Credenciales incorrectas. Verifique e intente nuevamente");
		}

	}

}

Para enviar datos devuelta al cliente lo haremos mediante un PrintWriter cuya instancia la obtenemos de la respuesta. Si las credenciales son incorrectas, enviamos el mensaje de vuelta al cliente: “Credenciales incorrectas. Verifique e intente nuevamente”. Si te fijas, enviamos junto con la respuesta el status HttpServletResponse.SC_BAD_REQUEST que es una constante que vale 400. Por lo que esa instrucción se traduce a:

response.setStatus(400);

Este mensaje lo capturamos mediante ajax.responseText en nuestro código JavaScript y lo mostramos en la notificación.

Imágenes (WebContent/img)

Necesitaremos la siguiente imagen para nuestro login:

logo

CSS (WebContent/css)

Por último, le damos un poco de estilo, algo flat y moderno 😉

html {
    box-sizing: border-box;
}

*, *:before, *:after {
    box-sizing: inherit;
    margin: 0px;
    padding: 0px;
}

body {
    align-items: center;
    display: flex;
    height: 100vh;
    justify-content: center;
}

form {
    display: block;
    height: 350px;
    width: 300px;
}

form > .header {
    align-items: center;
    display: flex;
    justify-content: center;
    width: 100%;
}

form > .header > img {
    background-size: cover;
    display: block;
    height: 150px;
    width: 150px;
}

form > .body {
    padding: 1rem;
    width: 100%;
}

form > .body > .input-group {
    display: flex;
    flex-flow: column nowrap;
}

form > .body > .input-group > input {
    border: 1px solid #eee;
    border-radius: 4px;
    color: #444;
    font-size: .9rem;
    padding: .7rem;
    transition: border-color .2s ease;
}

form > .body > .input-group > input:last-child {
    margin-top: 10px;
}

form > .body > .input-group > input:focus {
    border-color: #1e90ff;
    outline: none;
}

form > .body > .btn-login {
    background-color: #3498db;
    border: none;
    border-radius: 4px;
    color: rgba(255, 255, 255, .9);
    font-size: .9rem;
    margin-top: 15px;
    padding: .8rem;
    transition: background-color .3s ease;
    width: 100%;
}

form > .body > .btn-login:hover {
    background-color: #2A82BD;
}

form > .body > .btn-login:focus {
	outline: none;
}

Genial, ya tenemos todo en orden para ejecutar. Ejecutamos el proyecto en GlassFish y nos dirigimos a http://localhost:8080/LoginAJAX/login.html, deberíamos de ver nuestra pantalla de login.

login-0

Si ingresamos una contraseña diferente a 12345, el servlet debe responder con un código 400 y un mensaje de error. Probamos y efectivamente tenemos la respuesta:

Pantalla de login

El código lo pueden encontrar en el branch 0.5 del repositorio para este tutorial en GitHub:

gitcat

Espero les haya gustado el post chicos. ¡Un saludo y nos vemos pronto!

Anuncios

2 comentarios en “Login básico con Servlets & AJAX

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s