Agenda de Contactos, Java Web App (I)

Como saben (los que siguen regularmente mi blog), soy un fanático de Java y escribo la mayorías de mis sistemas en dicho lenguaje.

El tema, es que me aburro fácilmente y siempre busco lenguajes nuevos (mi cliente twitter en python, unas entradas sobre C# , etc) y trato de aprender todos los lenguajes que pueda.

Actualmente estoy enganchado (muy enganchado) con Scala (creo que mencioné algo sobre esto algunas entradas atrás) … y como siempre digo, la mejor forma de aprender es haciendo (Inacapino de corazón😀 )

En la universidad, y a modo de evaluación para mis alumnos de 2 año (Java Web) hicimos una agenda de contactos (agregar y ver contactos) lo suficientemente simple para hacerlo en una clase, pero con la mayor cantidad de elementos vistos en las clases.

Visualmente, es algo así:

Login

Login

Y

Listado Contactos agregados

Listado Contactos agregados

Área de trabajo 1_011

Formulario ingreso contacto

Eso es todo.

Paso a paso:

Mostrar nombre “dueño” agenda

Éste dato lo obtenemos del “login” de la primera página. El formulario del login es así

<form class="form-signin" action="ServletAgenda" method="post">
  <h2 class="form-signin-heading">Iniciar Sesión</h2>
  <input type="hidden" name="action" value="login"/>
  <input type="text" class="form-control" placeholder="Nombre Usuario" autofocus name="txt_nombre_usuario">
  <button class="btn btn-lg btn-primary btn-block" type="submit">Ingresar</button>
</form>

Envía la información a ServletAgenda. A su vez, en el servlet tenemos (esto por parte, así que el código no va a funcionar de buenas a primeras).

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  response.setContentType("text/html;charset=UTF-8");
  PrintWriter out = response.getWriter();
  try {
    HttpSession sesion = request.getSession();
      switch (request.getParameter("action")){
        case "login":
          /* INICIAR SESION */
          sesion.setAttribute("NombreUsuario", request.getParameter("txt_nombre_usuario"));
          sesion.setAttribute("Contactos", new ArrayList<Contacto>());
          response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/agenda.jsp"));

Entonces, creo una sesión nueva (si no existe) y dependiendo del valor del parámetro action (en caso de ser login) escribo los atributos NombreUsuario y Contactos (lista de tipo Contacto)y redirijo a la página agenda.jsp

A su vez, agenda tiene:

<core:choose>
  <core:when test="${empty sessionScope.NombreUsuario}">
    <div class="alert alert-danger">
      <strong>Atención !</strong>
      <a href="index.jsp">Favor Iniciar Sesión</a>
    </div>
    </core:when>
    <core:otherwise>
      <h3>Mostrando Contactos de usuario <core:out value="${sessionScope.NombreUsuario}"></core:out></h3>
      <!-- más adelante -->
    </core:otherwise>
</core:choose>

Usando JSTL revisamos si el atributo NombreUsuario existe o no, revisando en el espacio de sesión. De no existir, muestro un mensaje para iniciar sesión. En caso contrario, lo muestro junto a mis contactos.

Cantidad Contactos

Si es mi primer ingreso, mi lista de contactos viene vacía y luego de ingresar uno, me muestra la cantidad y cuáles son:

<core:choose>
  <core:when test="${empty sessionScope.Contactos}">
    <div class="alert alert-warning">
      <strong>Atención !</strong>
      Aún no tienes Contactos en tu agenda😦
    </div>
  </core:when>
  <core:otherwise>
    <h4>Cantidad Contactos: <core:out value="${sessionScope.Contactos.size()}"></core:out></h4>
    <!-- más adelante -->

Y listo. Reviso de la misma manera que el nombre y luego ocupo el método size() que tienen todos los List.

Tabla Contactos

Esto lo generamos así:

<table class="table table-bordered table-hover">
  <thead>
    <tr>
      <th>Nombre</th>
      <th>Teléfono</th>
      <th>E-Mail</th>
      <th>Dirección</th>
      <th>Llamadas</th>
      <th>Llamar</th>
    </tr>
  </thead>
  <tbody>
    <core:forEach items="${sessionScope.Contactos}" var="contacto">
    <tr>
      <td><core:out value="${contacto.getNombre()}"></core:out></td>
      <td><core:out value="${contacto.getTelefono()}"></core:out></td>
      <td><core:out value="${contacto.getEmail()}"></core:out></td>
      <td><core:out value="${contacto.getDireccion()}"></core:out></td>
      <td><core:out value="${contacto.getLlamadas()}"></core:out></td>
      <td>
        <form action="ServletAgenda" method="post">
          <input type="hidden" name="action" value="llamar" />
          <input type="hidden" name="num_a_llamar" value="<core:out value="${contacto.getTelefono()}"></core:out>" />
          <button type="submit" class="btn">Llamar <span class="glyphicon glyphicon-earphone"></span></button>
        </form>
      </td>
    </tr>
    </core:forEach>
  </tbody>
</table> 

Recorremos con un for:each usando la variable contacto a modo de tipo Contacto, la cual tiene la siguiente estructura:

public class Contacto {

    private String Nombre, Telefono, Email, Direccion;
    private Integer Llamadas;

    public Contacto() { }

    public Contacto(String Nombre, String Telefono, String Email, String Direccion) {
        this.Nombre = Nombre;
        this.Telefono = Telefono;
        this.Email = Email;
        this.Direccion = Direccion;
        this.Llamadas = 0;
    }

    //GETS y SETS

    public void addLlamada(){
        this.Llamadas += 1;
    }
}

En la tabla, cada contacto tiene un botón para simular una llamada al contacto. El atributo Telefono se considera como el ID del contacto.

Eso es todo por parte de lo visual. Seguimos con la lógica. Para hacerlo más corto, todo el peso cae sobre el servlet.

Agregar contacto

Código:

case "nuevoContacto":
  //ASIGNANDO ATRIBUTO A VARIABLE
  List<Contacto> contactos = (List<Contacto>) sesion.getAttribute("Contactos");
  //CAMPOS EN BLANCO, Nombre o Teléfono
  if(request.getParameter("nombreContacto").isEmpty() || request.getParameter("telefonoContacto").isEmpty()){
    request.setAttribute("Mensaje", "Necesito Nombre y Teléfono contacto");
    request.setAttribute("TipoMensaje", "danger");
  }else{
    //TELÉFONO ÚNICO
    //RECORRER LISTADO
    Boolean existe = false;
    String deContacto = "";
    for(Contacto C : contactos){
      if(C.getTelefono().equals(request.getParameter("telefonoContacto"))){
        existe = true;
        deContacto = C.getNombre();
        break;
      }
    }
    if(!existe){
      contactos.add(
        new Contacto(
          request.getParameter("nombreContacto"),
          request.getParameter("telefonoContacto"),
          request.getParameter("mailContacto"),
          request.getParameter("direccionContacto")
        )
      );
      request.setAttribute("Mensaje", "Nuevo Contacto Agregado");
      request.setAttribute("TipoMensaje", "success");
    }else{
      request.setAttribute("Mensaje",
      "Teléfono ya existe en Agenda. Pertenece a: " + deContacto);
      request.setAttribute("TipoMensaje", "warning");
    }
  }
  sesion.setAttribute("Contactos", contactos);
  request.getRequestDispatcher("agenda.jsp").forward(request, response);

Como vimos antes, el número es el identificador del contacto, por lo tanto, no puede repetirse. Si no encontramos el número, guardamos el contacto reemplazando la lista antigua por la nueva (una forma de hacerlo), y redirigimos a la página de la agenda.

Llamar a contacto

Cada contacto tiene un botón para llamarlo, el código es el siguiente:

case "llamar":
  //BUSCAR PERSONA
  //USANDO ATRIBUTO DE SESIÓN DIRECTAMENTE
  int index = 0; //INDICA ÍNDICE DE CONTACTO
  for(Contacto C : (List<Contacto>) sesion.getAttribute("Contactos")){
    if(C.getTelefono().equals(request.getParameter("num_a_llamar"))){
      //ENCONTRADO
      ((List<Contacto>)sesion.getAttribute("Contactos"))
        .get(index).addLlamada();
      request.setAttribute("Mensaje", "Contacto llamado");
      request.setAttribute("TipoMensaje", "info");
      break;
    }else{
      index++;
    }
  }
  request.getRequestDispatcher("agenda.jsp").forward(request, response);

Buscamos el contacto que tiene el número indicado y luego llamamos al método de llamar. Todo esto sobre la misma lista, sin crear una lista nueva y sobreEscribir.

Eso es todo. Bonito y funciona, pero tiene un problema … cuando cerramos sesión perdemos los contactos. Ésto porque la información es temporal (guardando en sesión). Para corregir esto, guardamos la info en una BD.

Seguimos con la siguiente parte del post😉

Dejo link al código fuente🙂 Dropbox

Acerca de MaritoCares

Ingeniero Informático. Con tendencias a la programación en [C#, VB].NET, Java(Web principalmente...), PHP, JavaScript, algo mínimo de [ruby, python], y el clásico C.
Esta entrada fue publicada en Java, Tutoriales. Guarda el enlace permanente.

4 respuestas a Agenda de Contactos, Java Web App (I)

  1. Cristian David dijo:

    Excelente, como hago para obtener el atributo Mensaje en el response, luego de haber procesado la solicitud. Gracias.

  2. EmanuelGuevara dijo:

    Que IDE utilizaste??

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s