Reimplementar administración de Usuarios en nuestra aplicación PrimeFaces/JSF/Spring/Hibernate (Parte 1/2)

Hola Estimad@s,

 

a continuación comenzaremos con una serie de cambios en nuestra aplicación a fin de implementar la persistencia de las cuentas de usuario con Hibernate, en esta primera parte solo inicializaremos las cuentas de usuario de los clientes y la cuenta admin, pero nos servirá para reforzar lo que hemos venido haciendo en los últimos posts.

 

Desarrollo

Comenzamos creando la clase Usuario, la cual encapsulará los datos pertenecientes a una cuenta de usuario.

 

Creamos las clases nuevas

Usuario.java (representa los datos de cuenta de un usuario)

package ar.com.magm.model;

public class Usuario {

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getNombre() {

return nombre;

}

public void setNombre(String nombre) {

this.nombre = nombre;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public boolean isAdmin() {

return admin;

}

public void setAdmin(boolean admin) {

this.admin = admin;

}

private int id;

private String nombre;

private String password;

private boolean admin;

}

Cliente.java (agregamos al final de la clase el atributo usuario)

...

        ...

        private Usuario usuario;

public Usuario getUsuario() {

return usuario;

}

public void setUsuario(Usuario usuario) {

this.usuario = usuario;

}

}

 

Creamos los mapeos nuevos

Usuario.hbm.xml (mapeo nuevo)

<?xml version="1.0" encoding="UTF-8"?>

 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "https://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="ar.com.magm.model.Usuario" table="usuarios">

<id column="id" name="id" type="integer" />

<property name="nombre" />

<property name="password" />

<property name="admin" />

</class>

</hibernate-mapping>

Cliente.hbm.xml (modificamos el existente)

   ...

   ...

      <many-to-one name="zona" class="ar.com.magm.model.Zona"

column="idZona"/>

      <many-to-one name="usuario" class="ar.com.magm.model.Usuario"

column="idUsuario"/>

   </class>

   ...

   ...

 
Hibernate.cfg.xml (modificamos el existente)
   ...

   ...

   <mapping resource="ar/com/magm/model/Usuario.hbm.xml" />

   <mapping resource="ar/com/magm/model/Cliente.hbm.xml" />

   ...

   ...

Definimos e implementamos los DAO

Lo que se plantea a continuación debería servirnos para reforzar el procedimiento a seguir para crear un nuevo DAO para una nueva clase del modelo.

UsuarioDAO.java (primero la interfaz con los servicios)

package ar.com.magm.persistencia.dao;

import ar.com.magm.model.Usuario;

public interface UsuarioDAO extends GenericDAO<Usuario, Integer> {}

 
UsuarioDAOImplHibernate.java (luego la implementación particular para Hibernate)

package ar.com.magm.persistencia.dao.hibernateimpl;

import ar.com.magm.model.Usuario;

import ar.com.magm.persistencia.dao.UsuarioDAO;

public class UsuarioDAOImplHibernate extends

                GenericDAOImplHibernate<Usuario, Integer> implements UsuarioDAO {

}

 
applicationContext.xml (modificamos el existente)

 ...

 ...

 <bean class="ar.com.magm.persistencia.dao.hibernateimpl.ZonaDAOImplHibernate" />

 <bean class="ar.com.magm.persistencia.dao.hibernateimpl.UsuarioDAOImplHibernate" />

 ...

 ...

Creamos el controlador

InicializaCuentasClientesController.java

package ar.com.magm.model.dao.controller;

import java.io.IOException;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Scope;

import org.springframework.stereotype.Component;

import ar.com.magm.model.Cliente;

import ar.com.magm.model.Usuario;

import ar.com.magm.persistencia.dao.ClienteDAO;

import ar.com.magm.persistencia.dao.UsuarioDAO;

import ar.com.magm.persistencia.exception.BussinessException;

@Component("inicializaCuentasClientesController")

@Scope("request")

public class InicializaCuentasClientesController {

  @Autowired

  private ClienteDAO clienteDAO;

  @Autowired

  private UsuarioDAO usuarioDAO;

  public void processRequest(HttpServletRequest request,

                    HttpServletResponse response) throws IOException {

    String salida = "";

    try {

      // Parte 1

      // Inicializamos usuario admin si no existe

      Usuario usuarioAdmin = usuarioDAO.get(33333);

      if (usuarioAdmin == null) { 

        usuarioAdmin = new Usuario();

        usuarioAdmin.setId(33333);

        usuarioAdmin.setAdmin(true);

        usuarioAdmin.setNombre("admin");

        usuarioAdmin.setPassword("admin");

        usuarioDAO.saveOrUpdate(usuarioAdmin);

        salida += "Inicializada cuenta admin.\n";

      } else {

         salida += "La cuenta admin ya se encontraba inicializada.\n";

      }

      int cuentasInit = 0;

      // Parte 2

      // Inicializamos cuentas de usuario de cada cliente si no existe

      List<Cliente> clientes = clienteDAO.findAll();

      for (Cliente c : clientes) {

        Usuario usuario = usuarioDAO.get(c.getIdCliente());

        if (usuario == null) {

          cuentasInit++;

          usuario = new Usuario();

          usuario.setId(c.getIdCliente());

          usuario.setAdmin(false);

          usuario.setNombre(c.getCliente());

          usuario.setPassword("Clave " + c.getIdCliente());

          c.setUsuario(usuario);

          usuarioDAO.saveOrUpdate(usuario);

          clienteDAO.saveOrUpdate(c);

        }

      }

      salida += "Cuentas de cliente inicializadas=" + cuentasInit;

    } catch (BussinessException ex) {

      ex.printStackTrace();

      salida = "Error inicializando cuentas de clientes y admin\n"

              + ex.getMessage();

    }

    response.getWriter().print(salida);

    response.getWriter().flush();

  }

}

 
El controlador en muy sencillo, consta de dos partes, en la primera comprueba si existe la cuenta "admin", a esto lo hace intentando cargar el id=33333, si no existe crea una instancia de Usuario y utiliza el método DAO saveOrUpdate() para almacenarlo.La parte 2 obtiene la lista de todos los clientes mediante el método DAO findAll(), luego chequeamos uno a uno si existe la cuenta de usuario asociada, si no existe se crea una y se asegura el almacenamiento.

En breve mejoraremos el mapeo de estas entidades para no tener que llamar a los métodos de persistencia de ambas.

Creamos el servicio
InicializarCuentasClientes.java

package ar.com.magm.web.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;

import org.springframework.web.context.support.WebApplicationContextUtils;

import ar.com.magm.model.dao.controller.InicializaCuentasClientesController;

@WebServlet("/InicializarCuentasClientes")

public class InicializarCuentasClientes extends HttpServlet {

  protected void doGet(HttpServletRequest request,

                     HttpServletResponse response) 

                     throws ServletException, IOException {

    ApplicationContext applicationContext = WebApplicationContextUtils

.getWebApplicationContext(this.getServletContext());

    InicializaCuentasClientesController controller = (InicializaCuentasClientesController) applicationContext

.getBean("inicializaCuentasClientesController");

    controller.processRequest(request, response);

  }

}

Nada que decir de este servicio, es similar a los anteriores, solo que utiliza otro controlador y que se ejecuta antes la URL /InicializarCuentasClientes, debemos agregar esta URL al filtro para disponer de sesiones Hibernate.

 

Agregamos la URL al filtro

HibernateContextListenerAndFilter

@WebFilter(urlPatterns = { "/TestHibernateConSpring", "*.xhtml", "/InicializarCuentasClientes" }) 

 

Creando las cuentas

Ahora solo debemos loguearnos al sistema y una vez en la pantalla principal cargar la URL: 'https://localhost:8080/pf/InicializarCuentasClientes'

 

La primera vez veremos el siguiente resultado:

 

Si lo ejecutamos nuevamente veremos:

 

 

Si chequeamos el estado de las tablas en MySQL (en este caso usando MySQL Query Browser):

Podemos ver que ya disponemos (de forma automática) de la clave foránea en la tabla Clientes.

 

Y se ha creado la tabla Usuarios:

 

Eso es todo por ahora, espero les sea de utilidad.

 

Saludos

Mariano