Servlets

Los servlets son una tecnología hermana de los JSP, como ya comentamos en el artículo sobre estos últimos.

Un servlet no es más que una clase que implementa la interfaz Servlet (que se encuentra dentro del paquete javax.servlet, como todas las clases e interfaces que comentaremos) o que extiende de la clase GenericServlet, que proporciona una implementación por defecto para los métodos definidos en la primera. GenericServlet es independiente del protocolo utilizado, si nuestro servlet sólo va a usar HTTP podemos heredar de la clase HttpServlet.

Para escribir un servlet que extienda GenericServlet tendremos que sobre escribir el método abstracto service() y añadir ahí el código que queramos que se ejecute cuando se llame al servlet. En el caso de HttpServlet la implementación por defecto del método service comprueba si la petición recibida era de tipo POST (los parámetros se pasan en la cabecera del mensaje) o de tipo GET (los parámetros están en la URL, luego son visibles para todo el mundo), y llama a los métodos doPost o doGet dependiendo de esto.

Tanto doGet como doPost reciben como parámetros objetos de tipo HttpServletRequest y HttpServletResponse.

De la clase HttpServletRequest nos interesa el método getParameter(String nombreParametro), que devuelve el valor del parámetro de nombre nombreParametro. Por ejemplo, si visitáramos la URL http://localhost:8080/ejemplo/hola?nombre=Raul&apellido=Gonzalez (vemos que es una petición GET, porque los parámetros se pasan en la URL) el servlet hola podría llamar a getParameter("nombre") para obtener el nombre o getParameter("apellido") para obtener el apellido.

De HttpServletRequest también nos interesa el método getSession(boolean crear), que nos devuelve un objeto de tipo HttpSession y cuyo parámetro indica si debería crearse una sesión o no para ese usuario en caso de que no exista ya. Una sesión es el mecanismo por el cual podemos identificar una serie de iteraciones de un cliente con nuestra aplicación, y guardar y obtener valores que se mantengan para ese usuario durante las distintas peticiones que haga durante la sesión. En castellano:

  1. Un usuario pide una de nuestras páginas JSP o uno de nuestros servlets, por ejemplo la página de login.
  2. Se crea una cookie (también se pueden usar otros métodos) en el navegador del usuario, con un identificador aleatorio.
  3. Ahora, en nuestro JSP o servlet podemos guardar valores cualquiera que podrán ser vistos por las demás páginas JSP o servlets de nuestra aplicación que visite el usuario. Por ejemplo guardamos el nombre de usuario que ha introducido.
  4. Si el usuario visita otra de nuestras páginas podemos obtener el valor que guardamos en la sesión. Por ejemplo, podemos obtener el nombre de usuario que guardamos e imprimirlo en la parte superior de la página con un “Bienvenido Zootropo”.

El método de HttpSession que se utiliza para guardar objetos en la sesión es setAttribute(String nombre, Object objeto) y el método que se utiliza para obtener los objetos que guardamos, getAttribute(String nombre). No obstante hay que tener en cuenta que los objetos que guardamos en la sesión deben ser serializables (implementar Serializable).

Un concepto similar al de las sesiones sería el de contexto de Servlet. Este permite guardar y recuperar valores, pero estos valores serán comunes para todos los usuarios de la aplicación. Se representa por un objeto ServletContext que obtenemos a partir del método getServletContext() de GenericServlet y tiene métodos getAttribute y setAttribute al estilo de la sesión.

De la clase HttpServletResponse nos interesa el método getWriter(), que devuelve un objeto de tipo PrintWriter con el que escribir en el navegador usando el método println(String texto) y sendRedirect(String url), que permite enviar al navegador una instrucción de redirección a la página que deseemos.

Similar a sendRedirect es el método forward(HttpServletRequest request, HttpServletResponse response) de la clase RequestDispatcher, que se diferencia en que es más rápido, porque se trata a nivel de servidor, pero no permite redireccionar a URLs externas a la aplicación. El objeto RequestDispatcher se obtiene a partir del request mediante el método getRequestDispatcher(String url).

Tanto sendRedirect como forward no hacen más que redirecciones, es decir, su objetivo no es el de escribir parte del documento y delegar después el resto a otro servlet; ese es el cometido del método include de RequestDispatcher.

Otros métodos de HttpServlet son init(), que se lanza al iniciar el servlet, y destroy(), que se lanza cuando se destruye. Hay que tener en cuenta que, dado que el proceso de creación de un servlet es muy costoso en tiempo, no se crea un nuevo servlet para cada petición del cliente (y evidentemente tampoco se destruye cuando se termina de procesar), lo cual implica, entre otras cosas, que init() y destroy() sólo se llaman una vez y que hay que andar con pies de plomo a la hora de usar variables de instancia dado que pueden provocar problemas de concurrencia. Esto también es así en el caso de los JSP, que como ya dijimos, no son más que servlets al fin y al cabo.

La forma de un servlet típico entonces sería algo así:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
public class MiServlet extends HttpServlet {
  public void init() throws ServletException {
    // Inicio
  }
	
  public void doGet(HttpServletRequest request, HttpServletResponse response)	throws ServletException, IOException {
    String nombre = request.getParameter("nombre");
    res.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("Hola" + nombre + "");
    out.close();
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try{
      doGet(request, response);
    }catch (Exception e){
      e.printStackTrace();
    }
  }
	
  public void destroy() {
    // Fin
  }
}

Comentarios
  1. Tus aclaraciones me han sido muy útiles. ¡Muchas gracias! :-)

    Responder

  2. Bueno, factorizando la parte que tenía menos clara: la diferencia entre sendRedirect y forward.

    - sendRedirect ocurre del lado del cliente (le decimos al navegador que haga una nueva petición a otra URL).

    - forward ocurre del lado del servidor. Por eso mismo sólo podemos acceder a un recurso local del servidor.

    Sólo añadir que con el forward, si estás rellenando un formulario, se conservan los campos que hayas escrito; lo cual es interesante si existe algún error en la introducción de los datos (por ejemplo, un email incorrecto) para no tener que escribir todo de nuevo.

    Responder

  3. pedro

    me gusta la explicación dada… felicidades

    Responder

  4. Soy de México y estoy viendo estos temas en la Universidad, están explicados claramente y me he despejado de varias dudas.

    Excelente sitio
    Felicidades!

    Responder

  5. kerne

    Muy buena picksh, estoy comenzando con esta historia y me quedo clarisimo el tema

    Responder

  6. fausto

    supongamos q quiero obtener la informacion del usuario con el getparameter desd un formulario html. pregunto. para que el metodo getparameter obtenga los valores de entrada desde el formulario html dentro de el formulario el atributo method tiene q tiene q tener el valor “get” ajuro? o puede tener “post?
    gracias

    Responder

  7. Dalton

    No importa que el metodo del form sea post o get, getParameter recibe como argumento el nombre del parametro y devuelve el valor. pero para hacerlo tiene dos metodos que hay que reescribir. doGet() y doPost(), asi que si envias tus parametros por get, reescribes doGet(), si los envias por el metodo Post, reescribes el doPost(), lo mas practico seria hacer una metodo generico que lea parametros y luego llamarlo desde el doPost() o doGet(), segun sea necesario.

    Nota: conocimientos empiricos, nada de lo que dije es verdad absoluta.

    Responder

  8. alexander

    me puedes explicar esta parte del codigo

    res.setContentType(“text/html”);

    Responder

  9. @alexander sirve para indicar el tipo mime del documento, en este caso un documento html.

    Responder

  10. [...] nuestra aplicación usando JSP, Servlets, JDBC, Hibernate, o cualquier otra tecnología que nos [...]

    Responder

  11. kaniojo

    ¿se puede pasar informacion desde un jsp a otro jsp? gracias soy nuevo en esto

    Responder

    • No se muy bien a qué te refieres kaniojo. Si te refieres a mantener una cierta información relativa a una persona a través de las distintas peticiones, si, puedes hacerlo mediante sesiones. Es un mecanismo que se basa en cookies o en reescritura de las URL, porque HTTP es un protocolo sin memoria.

      El uso de sesiones está explicado en el texto.

      Responder

  12. [...] supuesto, podríamos utilizar JSP y servlets para crear una aplicación utilizando el patrón MVC: en una aplicación con JSP y servlets [...]

    Responder

  13. Carolina

    Estoy utilizando un servlet para descargar un archivo dwg, pero no se como capturar el valor del evento Guardar y Cancelar, ya que dependiendo de la selección que relice el usuario debo cambiar unas banderas en la base de dato. Alguien sabe como capturo estos valores?

    Responder

  14. mokoko

    Estoy enviando parametros de un form.html a un servlet, del servlet lo direcciono a un jsp mediante sendRedirect(“mijsp.jsp”);
    La duda que tengo, es como rescatar los parametros enviados del formulario?

    Responder

  15. yamil

    Hola ya entendi el codigo y lo que explicaste
    pero abra alguna manera de volver a invocar a otra pagina o a la misma pagina que mando a llamar al servlet?

    Responder

  16. paola

    Es que quiesiera saber o que me dieran un ejemplo de como funciona el requestDispacher para que sirve y todo eso.

    Solo quiero tener una idea bien clara porfa…

    Gracias

    Responder

  17. pongan un ejemplo con RequestDispatcher

    Responder

Deja un comentario