Primero que nada, necesitamos crear nuestro fichero
index.jsp o
index.html que contendrá el formulario de ingreso. Éste fichero va dentro del folder
webapp, WebContent o WebPages (de acuerdo al IDE):
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> <link rel="stylesheet" href="assets/css/login.css"/> <div id="flogin" class="flogin"> <section class="left-side">
<section class="head">
LOGIN
</section>
<section class="body">
<section class="data">
<section class="form-group">
<section class="input-wrapper">
<input type="text" id="txt-username" class="txt"/> <i class="fa fa-user"></i> </section>
</section>
<section class="form-group">
<section class="input-wrapper">
<input type="password" id="txt-password" class="txt"/> <i class="fa fa-key"></i> </section>
</section>
</section>
<section class="help">
<a href="">¿Olvidaste tu usuario o contraseña?
</a> </section>
</section>
</section>
<section id="btn-login" class="right-side">
<i class="fa-4x fa fa-arrow-right"></i> </section>
<!-- javascript files -->
CSS:
* {
margin: 0px;
padding: 0px;
}
body {
align-items: center;
background-color: #f9f9f9;
display: flex;
height: 100vh;
justify-content: center;
}
.flogin {
display: flex;
justify-content: space-between;
width: 400px;
}
.flogin > .left-side {
background-color: #363636;
border: 9px solid #dedede;
border-right: none;
border-radius: 20px 0px 0px 20px;
width: 80%;
}
.flogin > .right-side {
align-items: center;
background-color: #34B5D5;
border: 9px solid #dedede;
border-left: none;
border-radius: 0px 20px 20px 0px;
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
padding: 1.3rem .2rem;
width: calc(20% - 2*.2rem - 9px);
}
.flogin > .right-side:hover {
cursor: pointer;
}
/*********************
LEFT SIDE
*********************/
.left-side > .head {
border-bottom: 2px dashed #ddd;
color: #eee;
font-family: "segoe ui";
margin-bottom: 20px;
padding: .75rem 1rem;
}
.left-side > .body {
padding: .8rem 1.35rem;
width: calc(100% * 2*1.35rem);
}
.body > .data {
display: flex;
justify-content: space-between;
}
.form-group {
width: 45%;
}
.form-group > span {
color: #ddd;
display: block;
font-family: "segoe ui";
font-size: 10pt;
margin-bottom: 7px;
}
.form-group > .input-wrapper {
align-items: center;
background-color: white;
border-radius: 5px;
box-shadow: 0px 2px 5px 1px rgba(0,0,0,.4) inset,
0px -1px 2px 1px rgba(0,0,0,.25) inset;
display: flex;
justify-content: space-between;
}
.input-wrapper > .txt {
width: 80%;
}
.input-wrapper > i {
color: gold;
width: 20%;
}
.txt {
background-color: transparent;
border: none;
border-radius: 5px;
padding: .4rem .25rem;
width: calc(80% - 2*.35rem - 2*1px);
}
.txt:focus {
outline: none;
}
.help {
display: flex;
justify-content: flex-end;
}
a {
color: #ddd;
display: block;
font-family: "segoe ui";
font-size: 10pt;
font-style: italic;
margin-top: 20px;
text-align: right;
text-decoration: none;
}
/*****************
RIGHT SIDE
*****************/
.right-side > i {
color: #fff;
display: block;
}
.right-side > span {
color: #fff;
display: block;
font-family: "segoe ui";
font-size: 16pt;
}
Como ven es código HTML simple, en el cual se construye un formulario. Ahora, escribamos el código javascript que nos permita hacer la llamada AJAX al futuro servlet. Éste fichero va dentro del folder assets/js:
document.addEventListener("DOMContentLoaded", init, true);
function init() {
document.querySelector("#btn-login").addEventListener("click", handleLogin, true);
function handleLogin(e) {
e.preventDefault();
var txtUsername = document.querySelector("#txt-username");
var txtPassword = document.querySelector("#txt-password");
var userdata = '{"username":'+txtUsername.value+',"password":'+txtPassword.value+'}';
loginByAjax(userdata);
resetForm();
}
function loginByAjax(data) {
var request = new XMLHttpRequest();
request.open("POST", "LoginController", true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.onreadystatechange = function() {
// si la respuesta fue exitosa
if(request.readyState == 4 && request.status == 200) {
var message = request.responseText;
alert(message);
}
// si la respuesta trajo error
else if(request.readyState == 4 && request.status != 200){
var message = request.responseText;
message = request.responseText;
alert(message);
}
};
request.send("userdata="+data);
}
function resetForm(form) {
var form = document.querySelector("#flogin");
var controls = form.querySelectorAll("input, select");
for(var i=0; i<controls.length; i++) {
var control = controls[i];
if(control.nodeName === "INPUT")
control.value = "";
else if(control.nodeName === "SELECT")
control.selectedIndex = 0;
}
controls[0].focus();
}
}
Como se puede observar, el código es muy sencillo. Escuchamos por evento
submit del formulario y le decimos que se ejecutará la función
handleLogin. Ésta función obtiene los valores ingresados en los textbox del formulario, crea un JSON en forma de texto y se lo envía al método
loginByAjax(data) para que se envíe al servlet mediante AJAX.
El método
loginByAjax tiene el siguiente código:
function loginByAjax(data) {
var request = new XMLHttpRequest();
request.open("POST", "LoginController", true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.onreadystatechange = function() {
// si la respuesta fue exitosa
if(request.readyState == 4 && request.status == 200) {
var message = request.responseText;
alert(message);
}
// si la respuesta trajo error
else if(request.readyState == 4 && request.status != 200){
var message = request.responseText;
message = request.responseText;
alert(message);
}
};
request.send("userdata="+data);
}
Como vemos, el código lo único que hace es hacer una llamada AJAX al servet
LoginController enviándole el parámetro recibido
data, que es el JSON en forma de texto:
request.send("userdata="+data);
Si la llamada AJAX funciona exitosamente, mostraremos la respuesta retornada desde el servlet en un alert:
if(request.readyState == 4 && request.status == 200) {
var message = request.responseText;
alert(message);
}
Caso contrario, se mostrará también el mensaje de error en un alert. Quizás te estés preguntando, porqué la condición:
if(request.readyState == 4 && request.status == 200)
La petición tiene 5 estados, que son:
- 0: Petición no inicializada
- 1: Conexión establecida con el servidor.
- 2: Petición recibida
- 3: Procesando petición
- 4: Petición finalizada y respuesta lista.
Así mismo, cada petición tiene muchos códigos de estado. El código 200 indica que la petición ha sido exitosa, 404 indica que el recurso no ha sido encontrado, 500, error del servidor, etc. Puedes ver la lista de códigos
aquí.
Entonces, el código anterior se puede traducir a:
Si la petición ha finalizado y la respuesta está lista, y además la petición ha sido exitosa...
Por último, reseteamos el formulario para limpiar los campos y colocar el foco en el textbox del nombre de usuario.
Ahora, nos queda crear nuestro servlet. Nuestro servlet se llamará
LoginController y tendrá el siguiente código:
package com.company.controllers;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;
@WebServlet(asyncSupported=true, urlPatterns={"/LoginController"})
public class LoginController extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger("LoginLogger");
public LoginController() {
super();
}
public void processRequest
(HttpServletRequest request, HttpServletResponse response
) throws ServletException,
IOException { response.setContentType("text/plain");
String strJson
= request.
getParameter("userdata"); // obtiene lo enviado por AJAX JSONObject json = new JSONObject(strJson);
if(username.equals("Duke") && password.equals("Duke777")) {
writer.print("Usuario correctamente identificado");
} else {
writer.print("Usuario o contraseña incorrectas");
}
writer.flush();
writer.close();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
try {
processRequest(request, response);
logger.warning(e.getLocalizedMessage());
}
}
@Override
protected void doPost
(HttpServletRequest request, HttpServletResponse response
) throws ServletException,
IOException { try {
processRequest(request, response);
logger.warning(e.getLocalizedMessage());
}
}
}
Nuestro servlet no es nada del otro mundo, es muy sencillo. Explicaré las siguientes lineas:
String strJson
= request.
getParameter("userdata"); // obtiene lo enviado por AJAX JSONObject json = new JSONObject(strJson);
¿Recuerdas que en el código AJAX enviamos el JSON con el nombre de usuario y contraseña en formato texto? Bien, y tenía como identificador
userdata.
Como ves, esa
variable userdata con el valor del JSON enviado desde AJAX, lo podemos obtener en nuestro Servlet mediante el método
getParameter, el cual obtiene un valor pasado por parámetro mediante su identificador.
En éste momento,
strJson es equivalente al JSON en forma de texto enviado desde AJAX:
var userdata = '{"username":'+txtUsername.value+',"password":'+txtPassword.value+'}';
Una vez que tenemos el valor enviado en nuestro servlet, lo que vamos a hacer es convertirlo a JSONObject:
JSONObject json = new JSONObject(strJson);
JSONObject hace uso de un objeto tipo Map para poder trabajar fácilmente con pares "llave - valor". Por lo que, por medio de la llave podemos obtener su valor. Las llaves son
username y
password, entonces, solo obtenemos sus valores:
Y por último, evaluamos si el usuario es
Duke y si la contraseña es
Duke777. Si es correcto enviaremos el mensaje
Usuario correctamente identificado o
Usuario o contraseña incorrecta de vuelta a la llamada AJAX.
Una vez que la respuesta ha sido devuelta a la llamada AJAX, solo la mostramos en un alert:
if(request.readyState == 4 && request.status == 200) {
var message = request.responseText;
alert(message);
}
// si la respuesta trajo error
else if(request.readyState == 4 && request.status != 200){
var message = request.responseText;
message = request.responseText;
alert(message);
}
CONCLUSIÓN
Como el lector se ha dado cuenta, comunicar servlets con AJAX es realmente muy sencillo, tan sencillo como en otros lenguajes
¡Hasta la próxima!