SERVLETS Y AJAX
El presente pequeño tutorial, tiene como finalidad mostrar cómo interactuar entre Servlets y javascript, mediante AJAX, tomando como ejemplo un formulario de ingreso.
(http://i.imgur.com/DV831bu.png)
Se asume que el lector tiene noción de las siguientes tecnologías:
- Lenguaje de programación Java
- HTTP
- Servlets
- javascript
- AJAX
Si no se tiene nociones de las mencionadas tecnologías, se puede seguir el tutorial, ya que se explicarán algunos puntos. De todas maneras, el lector debe de investigar cada punto, término, trozo de código o afines que no entienda.
Herramientas necesarias
Para seguir perfectamente éste tutorial, se necesitarán las siguientes herramientas:
- Eclipse Luna EE: IDE para programación en Java Enterprise Edition. No solo soporta el API estándar de Java, si no que también nos brinda soporte para la API empresarial.
- NetBeans Java EE. Gran IDE con muy buen soporte para Java Enterprise Edition. Excelente editor de código y muy buen auto completado.
- GlassFish: Servidor para aplicaciones Java web.
- org.json.jar: Librería que nos permite transformar un Map o String a JSONObject y viceversa.
Zona de descargas
- Eclipse Luna EE (https://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/lunasr2)
- NetBeans EE (https://netbeans.org/downloads/)
- GlassFish (http://dlc.sun.com.edgesuite.net/glassfish/4.1/release/glassfish-4.1.zip)
- Java JSON (http://central.maven.org/maven2/org/json/json/20141113/json-20141113.jar)
Notas de aclaración
Dada la simpleza que requiere éste tutorial, NO se empleará un gestor de base de datos. El objetivo del presente documento es mostrar de forma práctica y sencilla, la comunicación entre servlets y AJAX.
CONFIGURACIÓN DE ECLIPSE E INSTALACIÓN DE GLASSFISH
Instalación de GlassFish Tools en Eclipse
Abrimos nuestro Eclipse Luna EE. Si es primer uso, se preguntará dónde desea que sea el espacio de trabajo, por defecto es en la carpeta de usuario pero se puede especificar donde se desea (siempre y cuando tengamos permisos).
Una vez abierto Eclipse, tenemos que instalar GlassFish Tools para poder instalar nuestro servidor GlassFish. Para ésto vamos a la opción Eclipse Marketplace del menú Help y buscamos "glassfish":
(http://i.imgur.com/kkWOcs7.png?1)
Hacemos click en Install. Nos preguntará si aceptamos la licencia, elejimos el radio button "Yes. I accept..." y empezará a instalar GlassFish Tools (Si pregunta algo durante la instalación, dale "Yes"). Al finalizar la instalación nos pedirá reiniciar Eclipse. Aceptamos.
Instalación de GlassFish 4.1
Descomprimimos el zip que nos hemos bajado de la web de GlassFish y lo colocamos en:
CitarC://Program Files/
De tal modo que la instalación de GlassFish quede así:
CitarC://Program Files/glassfish/
Abrimos Eclipse y nos dirigimos hacia la opción Preferences del menú Window. Aquí desplegamos el menú Server -> Runtime Environments:
(http://i.imgur.com/8ILCy3n.png?1)
Hacemos click en Add y nos mostrará una ventana con los adaptadores de servidores disponibles. Escogemos GlassFish 4 y hacemos click en Next:
(http://i.imgur.com/TiwvTve.png?1)
En la siguiente cara, tendremos que especificar la dirección de la instalación de GlassFish y el JDK:
(http://i.imgur.com/lneA9IK.png?1)
NOTA: Es bien importante que el elemento en "Java development kit" sea el JDK y no el JRE. Si les aparece JRE deben de agregar un nuevo "installed JRE" dentro de Java -> Installed JREs. Para ésto solo basta hacer click en Add y agregar la ruta del JDK de Java.
Por último hacemos click en Next, dejamos todo por defecto y hacemos click en Finish para finalizar. Ya tenemos nuestro IDE listo para empezar a programar.
INSTALAR NETBEANS Y GLASSFISH
Al momento de instalar NetBeans Java EE, GlassFish viene incorporado. También Tomcat, pero pueden elegir no instalarlo sacando el checkbox de Tomcat 8:
(https://www.liberiangeek.net/wp-content/uploads/2014/03/netbeansubuntu_thumb.png)
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>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Identfíquese</title>
<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"/>
</head>
<body>
<div id="flogin" class="flogin">
<section class="left-side">
<section class="head">
LOGIN
</section>
<section class="body">
<section class="data">
<section class="form-group">
<span>Usuario:</span>
<section class="input-wrapper">
<input type="text" id="txt-username" class="txt"/>
<i class="fa fa-user"></i>
</section>
</section>
<section class="form-group">
<span>Contraseña:</span>
<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>
<span>IR</span>
</section>
</div>
<!-- javascript files -->
<script src="assets/js/login.js"></script>
</body>
</html>
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: