Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Objetivo
Entender el funcionamiento bsico de las aplicaciones web que se ejecutan del lado del
servidor
Desarrollar una aplicacin web bsica usando la tecnologa de CGI y usando Servlets
Comprender los principales retos que se presentan al desarrollar aplicaciones web
usando CGI y Servlets
Enunciado
La empresa Los Alpes requiere una aplicacin web sencilla que permita registrar los datos
interesados en sus productos. Por un lado, la aplicacin web debe permitir a los usuarios ingresar
un nombre y un correo electrnico. Los datos de cada usuario se debern guardar en un archivo
de texto.
Por otro lado, los empleados de la empresa podrn consultar los usuarios que se han registrado.
Cualquier empleado podr ingresar el nmero de usuarios que desea consultar (un nmero n).
En respuesta, la aplicacin deber mostrar solo los datos de esa cantidad usuarios (los datos de
los primeros n usuarios). En caso que el empleado ingrese un nmero mayor al nmero de
usuarios registrados (es decir, n es mayor al nmero de registros en el archivo) la aplicacin
deber mostrar los datos de todos los usuarios.
La empresa Los Alpes quiere evaluar la facilidad de desarrollo de (1) la aplicacin usando
tecnologa CGI (Common Gateway Interface) con el lenguaje de programacin C y corriendo
sobre el servidor Apache httpd, con respecto a (2) la aplicacin desarrollada con la tecnologa de
Servlets en el lenguaje de programacin Java (por ejemplo, corriendo en el servidor de
aplicaciones Glassfish).
<stdio.h>
<string.h>
<stdlib.h>
cgic.h
NOTA: Note que la librera cgic.h se importa de manera diferente, esto se hace para indicar al
compilador que la librera, en este caso cgic, se encuentra en el mismo directorio que el script
que lo va a usar.
3. Todas las aplicaciones en C deben tener un mtodo main(), para nuestro caso y por
hacer uso de la librera cgic, usaremos el mtodo cgiMain() como punto de entrada de
nuestro programa, dejando a cgic.c la responsabilidad de implementar el main()
4. Para cada peticin que ejecute el programa, el llamado de los mtodos se debe hacer en
el siguiente orden:
int cgiMain()
peticin
Petici
void
handlePostSubmit()
void
printFooter()
void
printHeader()
peticin
return 0
void
handleGetSubmit()
5. En C para usar un mtodo, este debe ser declarado antes de su utilizacin. Declare los
mtodos inmediatamente despus de la importacin de libreras.
void
void
void
void
HandlePostSubmit();
HandleGetSubmit();
printHeader();
printFooter();
8. Para imprimir cada lnea de la respuesta, usaremos el mtodo fprintf(), usando como
parmetros cgiOut (el stream de comunicacin con el navegador/cliente) y los datos (por
ejemplo un string) que se van a enviar de regreso.
void printHeader()
{
/* Enva el tipo de contenido de la respuesta */
cgiHeaderContentType("text/html");
fprintf(cgiOut, "<HTML><HEAD>\n");
fprintf(cgiOut, "<TITLE>Simple CGI</TITLE></HEAD>\n");
fprintf(cgiOut, "<BODY><H1>Simple CGI</H1>\n");
}
11. Despus, el mtodo handlePostSubmit(), el cdigo debe crear la cadena que va a ser
guardada en el archivo. Para esto debe declarar un nuevo arreglo de tipo char, donde el
tamao debe ser la suma del tamao del arreglo name, el tamao del arreglo email y
unos caracteres extra que incluyen la separacin de nombre y e-mail y el salto de lnea.
Las funciones strcpy() y strcat() sirven para crear copiar y concatenar los arreglos.
/* Declara una cadena para almacenar los dos datos */
char data[sizeof(name) + sizeof(email) + 6];
/* Copia en data los datos del nombre y el correo electrnico */
strcpy(data, name);
strcat(data, " - ");
strcat(data, email);
strcat(data, "\n");
13. Por ltimo, el mtodo handlePostSubmit(), abre el archivo de datos para concatenar
los datos del usuario. Usamos fopen para cargar el archivo DATAFILE y pasamos la
opcin a para indicar que lo que escribamos sobre el no sobreescribe lo que ya estaba
guardado. La funcin fputs la usamos para escribir el arregla data sobre el archivo.
/* Abre el archivo con la opcin a (append) */
FILE *f = fopen(DATAFILE, "a");
/* No fue posible abrir el archivo? */
if (f == NULL)
{
fprintf(cgiOut, "<p>Ocurri un error, no podemos guardar sus
datos</p>");
}
/* Fue posible abrir archivo? */
else
{
/* Guarda los datos en el archivo */
fputs(data, f);
/* Envia los datos en la respuesta al navegador */
fprintf(cgiOut, "<h1> %s </h1>\n", data);
/* Cierra el archivo */
fclose(f);
}
}
14. El mtodo handleGetSubmit() ser usado para recibir un entero n por parte del usuario
e imprimir los primeros n registros guardados en el archivo de datos. Declare un entero
para guardar el nmero ingresado por el usuario y use el mtodo cgiFormInteger, de la
librera CGIC, que recibe como parmetros el nombre del campo definido en el HTML, la
variable donde se va aguardar el valor y el valor por defecto que debe retornar en caso
de fallo. Adems defina un arreglo de tipo char con tamao 168 (tamao mximo que
puede ser guardado en el mtodo handlePostSubmit())
void handleGetSubmit()
{
/* Declara un valor entero */
int max_num;
/* Obtiene el valor ingresado por el usuario */
cgiFormInteger("max_num", &max_num,0);
char line[168];
15. El mtodo handleGetSubmit() debe leer el archivo de datos, lea tantas lneas como el
usuario haya solicitado del archivo de datos y use la funcin fprintf para escribir cada
lnea en la respuesta. Para leer cada lnea del archivo use la funcin fgets que recibe
como parmetro un arreglo donde va guardar el resultado, el tamao mximo que puede
tener la lnea (en este caso 168) y el archivo ledo. En caso de no poder leer el archivo
debe indicarlo al usuario en la respuesta
FILE *f = fopen(DATAFILE, "r");
if (f == NULL)
{
fprintf(cgiOut, "<TITLE>Fall</TITLE>\n");
fprintf(cgiOut, "<p><EM>No fue posible abrir el archivo de
datos</EM></p>\n");
}
else
{
fprintf(cgiOut, "<h1>Los datos almacenados</h1>");
int i = 0;
while (fgets(line, 168, f) && i<max_num)
{
fprintf(cgiOut, "<h2>%s</h2>\n\n", line);
i++;
}
}
fclose(f);
}
8. El mtodo doPost se encarga de procesar las peticiones POST y vamos a recibir del
formulario un campo name y un campo email. Cuando recibamos un par de datos
vamos a guardarlos en un archivo de texto con el formato name - email. Al usuario
vamos a mostrarle los datos que fueron guardados.
a. Primero al objeto response vamos a asignarle el tipo de documento que vamos
a retornar, para este caso ser text/html.
b. Despus vamos a cargar la instancia de la clase DataProcessor que es un
singleton y es la encargada de leer y escribir en el archivo de datos.
9. Cree un paquete nuevo dentro de Source Packages con el nombre classes, En el cree
la clase DataProcessor como un singleton.
a. En el contructor inicialice el archivo data.txt en la ubicacin que desee que los
datos queden guardados.
b. Cree el mtodo writeData que recibe como parametros los Strings name y
email y guardan en cada lnea la cadena name - email.
c. Cree el mtodo readData que recibe como parmetro un entero number y que
retorna un ArrayList con las primeras number entradas.
10. Abra el archivo web.xml que creamos anteriormente, en la parte superior seleccione la
pestaa Servlets y haga click en Agregar Servlet. Escriba el nombre del servlet y en la
clase busque el servlet creado, como patron URL escriba /MainServlet.
11. Vuelva a la pestaa Source y ver que se agregaron unas lneas como las siguientes:
<servlet>
<servlet-name>MainServlet</servlet-name>
<servlet-class>servlets.MainServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern>/MainServlet</url-pattern>
</servlet-mapping>
Lo que hace el mtodo reservado doPost es procesar las peticiones POST cuando se acceda al
servlet, aqu vamos a guardar los datos ingresados por el usuario en el ArrayList definido
anteriormente. En el mtodo doGet vamos a procesar las peticiones GET, lo que vamos a hacer
en este mtodo es leer los primeros n Strings con n un entero ingresado por el usuario.
<!DOCTYPE html>
<html>
<head>
<title>Registro</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<!DOCTYPE html>
<h1 align=center>Hola</h1>
<hr>
<form method='POST' action='MainServlet'>
<p>Como es tu nombre?</p>
<input type='text' name='name' value=''>
<p>como es tu correo?</p>
<input type='text' name='email' value=''>
<input type='submit' value='submit'>
</form>
<hr>
<form method="GET" action='MainServlet'>
<p>Consulta
<input type="number" min="1" name="max_num" value="1">
<input type='submit' value='submit'>
</form>
</body>
</html>
Para iniciar la aplicacin haga clic derecho sobre el proyecto web, despus haga clic en Run
para compilar y ejecutar sobre el servidor configurado. Por defecto la aplicacin corre sobre el
puerto 8080, ingrese a http://localhost:8080/ServletApp/ para ejecutar la aplicacin.