No importa cual compleja una pagina parezca, el proceso siempre es el mismo: el navegador envÃa una solicitud (request) y el servidor envÃa una respuesta de regreso. Es parte de protocolo HTTP. Aun AJAX usa el mismo principio.
Un servlet es una clase Java capaz de procesar una solicitud y generar una respuesta. Solo es necesario crear una clase que herede de la clase HttpServlet.
Los servlets son ejecutados por un contenedor web (también llamado contenedor servlet) que se encarga de crear una instancia de la clase y ejecutar los métodos necesarios para servir una solicitud.
Por medio de un archivo web.xml, le informamos al contenedor que URL se deben usar para acceder al servlet.
En este post vamos a construir un pequeño servlet. Usaremos NetBeans, solo porque cuando instalamos NetBeans, también instalamos los servidores Tomcat y GlashFish. Ambos funcionan como contenedores web que podemos utilizar para ejecutar nuestro servlet.
En otro post veremos como podemos utilizar Eclipse, aunque los pasos son prácticamente igual en cualquier interfaz de desarrollo que uses.
Abre NetBeans y crea un nuevo proyecto (Archivo -> Nuevo Proyecto).
Selecciona Java Web de la lista de CategorÃas. En lista de Proyectos, selecciona Aplicación Web. Haz clic en Siguiente (Next).
En la siguiente pantalla puedes nombrar el proyecto y elegir una ubicación.
Yo he nombrado mi proyecto ServletSample. Haz clic en Siguiente.
En la pantalla siguiente es donde elegimos el servidor que queremos utilizar con nuestro proyecto, al igual que la versión de Java.
También definimos una Ruta de Contexto (Context Path) para la aplicación web. Esta es la base de la URL para acceder la aplicación. Al final de este ejemplo podrás ver como es utilizado en la URL.
Usare el servidor Tomcat y Java 5. Y usare la ruta de contexto por defecto. Haz clic en Siguiente.
Esta pantalla nos permite elegir diferentes frameworks que nos pueden ayudar a construir aplicaciones web mas complejas rápidamente.
No usaremos ningún framework para este ejemplo. Haz clic en Terminar (Finish).
En este momento, tenemos una aplicación web con una sola pagina: index.jsp. Hablaremos acerca de JSP en otro post.
Estamos listos para crear un servlet. Pero primero, vamos a crear un par de clases para formar nuestra capa de negocio (business layer).
Agrega una nueva Clase Java al proyecto: clic derecho en el proyecto -> Nuevo -> Clase Java.
Nombra la clase Product y escribe ServletSample.Business en el campo Paquete (Package). Haz clic en Terminar.
Vamos a agregar unas cuantas propiedades y constructores a la nueva clase.
package ServletSample.Business; public class Product { private int id; private String name; private float price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public Product(){ this.id = -1; this.name = ""; this.price = 0f; } public Product(int id, String name, float price) { this.id = id; this.name = name; this.price = price; } }
Truco: después de que defines un campo privado, puedes hacer que NetBeans auto-genere los métodos get y set haciendo clic derecho en el nombre de la variable -> Refactor -> Encapsular Campos (Encapsulate Fields).
Esta clase representara un producto en nuestra aplicación.
Agrega otra clase al proyecto, nómbrala ProductService y también colócala en el paquete ServletSample.Business.
Vamos a agregar un par de métodos a esta clase.
package ServletSample.Business; import java.util.List; import java.util.ArrayList; public class ProductService { public List<Product> getProducts(){ List<Product> products = new ArrayList<Product>(); products.add(new Product(1,"HP Laptop",799f)); products.add(new Product(2,"IBM Desktop",599f)); products.add(new Product(3,"Cannon Printer",159f)); return products; } public Product getProduct(int id) { Product product = null; switch(id) { case 1: product = new Product(1,"HP Laptop",799f); break; case 2: product = new Product(2,"IBM Desktop",599f); break; case 3: product = new Product(3,"Cannon Printer",159f); break; } return product; } }
El primer método retorna una lista de productos, mientras que el segundo método retorna un producto especifico. En una aplicación real, estos métodos probablemente harÃan una llamada a una base de datos.
Ahora vamos a agregar un nuevo servlet a nuestro proyecto: clic derecho en el proyecto -> Nuevo -> Servlet.
Recuerda, un servlet es solo una clase que hereda de HttpServlet. Nombra la nueva clase ProductServlet. Vamos a crear esta clase en el paquete ServletSample.Web. Haz clic en Siguiente.
La siguiente pantalla nos permite configurar el servlet. Se encargara de agregar la definición del servlet al archivo web.xml.
Cambia el Patrón URL (URL Pattern) como se muestra arriba. Esta es la parte de la URL después de la ruta de contexto que vamos a utilizar para llamar el servlet desde el navegador. Haz clic en Terminar.
Después de un poquito de limpieza, el nuevo servlet se ve asÃ.
package ServletSample.Web; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ProductServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { } finally { out.close(); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
Cuando una solicitud GET se hace al servlet, el método doGet es llamado por el contenedor. Similarmente, el método doPost es llamado cuando un solicitud POST es hecha. Esto quiere decir que podemos ejecutar diferente código para cada tipo de solicitud. Si no queremos soportar un tipo de solicitud todo lo que tenemos que hacer es remover el método correspondiente.
En este caso, el mismo código es ejecutado para ambos tipos de solicitud, asà que en ambos métodos llamamos al método processRequest.
Ambos métodos reciben un objeto request que nos permiten obtener información sobre la solitud del navegador, como parámetros y cookies.
También toman un objeto response que nos permite generar la respuesta que se ha de enviar al navegador. Podrás observar que llamamos el método getWriter para obtener un objeto PrintWriter. Utilizaremos este objeto para escribir nuestra respuesta HTML.
Vamos a agregar nuestro código para generar una pagina web dentro de processRequest.
package ServletSample.Web; import ServletSample.Business.Product; import ServletSample.Business.ProductService; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ProductServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ProductService service = new ProductService(); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { String value = request.getParameter("id"); if (value != null) { int id = Integer.parseInt(value); Product product = service.getProduct(id); out.println("<h1>Product Details</h1>"); out.printf("<div>ID: %d</div>", product.getId()); out.printf("<div>Name: %s</div>", product.getName()); out.printf("<div>Price: $ %.2f</div>", product.getPrice()); out.printf("<div><a href=\"product\">Go Back</a></div>", product.getId()); } else { out.println("<h1>Product List</h1>"); out.println("<table>"); out.println("<tr><td><b>Name</b></td><td><b>Options</b></td></tr>"); for (Product product : service.getProducts()) { out.println("<tr>"); out.printf("<td>%s</td>", product.getName()); out.printf("<td><a href=\"product?id=%d\">Details...</a></td>", product.getId()); out.println("</tr>"); } out.println("</table>"); } } finally { out.close(); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
Primero creamos una instancia de la clase ProductService.
Con el método getParameter del objeto request obtenemos el valor de un parámetro llamado id. Si dicho parámetro fue enviado por el navegador, mostramos los detalles del producto correspondiente. Si el parámetro no existe, mostramos una lista de todos los productos.
Para mantener el ejemplo corto, no estamos validando que el parámetro id sea en realidad un numero. El navegador trata todos los parámetros como cadenas de texto (String). Tampoco estamos validando que un producto con esa id exista.
Ejecuta el proyecto (F6 si estas utilizando NetBeans). Escribe product al final de la URL.
No estamos pasando ningún parámetro en la URL, asà que la lista de productos aparecerá.
Cada vinculo es un vinculo al mismo servlet, pero con el parámetro correspondiente. Haz clic en uno de los vÃnculos.
Puedes hacer clic en el vinculo para regresar a la lista de productos.
Por favor deja un comentario si tienes alguna pregunta o sugerencia.