UploadFile con Icefaces + Hibernate + Anotaciones

2
11038

UploadFile con Icefaces + Hibernate + Anotaciones.

0. Índice de contenidos.

1. Introducción

Este tutorial pretende servir de gu
de inicio
para todos aquellos usuarios que comienzan a dar sus primeros pasos en ICEfaces,
JSF e Hibernate,y también,como pueden servirse de Netbeans IDE como entorno de desarrollo
fácil e intuitivo para dar soporte a estas tecnologías,
confeccionando de una manera rápida nuestro entorno de trabajo.

Objetivos

  • 1.Manejar comoponentes ICEfaces para la interfaz de usuario.
  • 2.Ver como JSF gestiona la capa de control,comunicando la presentación con la lógica de negocio.
  • 3.Servirnos de Hibernate para obtener una capa de persistencia más sencilla y mantenible.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Dell Latitude E5500(Core Duo T9550 2.66GHz, 4GB RAM, 340 GB HD).
  • Sistema operativo: Windows XP.
  • JDK 1.6.0_1
  • NetBeans 6.5
  • Icefaces 1.8.0
  • Hibernate 3.2.5
  • Tomcat 6.0.18
  • MySQL 5.1
  • Internet Explorer

3. La aplicación

La aplicación consiste en un listado donde se muestra los ficheros que tenemos en nuestro servidor. Podría quedar algo como:



y una pantalla de edición de los ficheros,tanto para editar uno existente como para subir un nuevo fichero.

4. Creando nuestro proyecto

Lo primero es crear un nuevo proyecto.

seleccionamos proyecto web.

Damos nombre a nuestro proyecto y le indicamos la ubicación de nuestro workspace

seleccionamos el servidor,en nuestro caso Tomcat.

y por último seleccionamos los frameworks necesarios.ICEfaces,JavaServerFaces e Hibernate 3.2.5 .

En el pantallazo no aparece pero Hibernate 3.2.5 esta el ultimo de la lista.

Nuestro proyecto quedaría algo como:

Podemos observar que en Libraries nos ha colocado todas las dependencias necesarias,además de crearnos los ficheros de configuración
de JSF (faces-config.xml) y el fichero de configuración de Hibernate(hibernate.cfg.xml) que veremos mas adelante.

5. Capa de Persistencia

La capa de persistencia son los cimientos de la aplicación.

Cualquier desarrollo por sencillo que sea,podría interactuar con una base de datos para insertar,modificar
y recuparar información.Aquí es donde entra en juego Hibernate facilitando el
proceso mediante mecanismos de mapeo objeto/relaccional(Object Relational Mapping,ORM) y
simplificando la programación de la capa de persistencia como veremos a continuación.


Dentro de la capa de persistencia hemos de diferenciar dos partes:

  • Definicion de las entidades persistentes de Hibernate
  • Definicion de los clases DAO ,que se encargaran de gestionar la logica de Hibernate,ya que nuestra lógica de negocio
    no tiene por qué saber como Hibernate gestiona el acceso a los datos.

5.1 Las Entidades

Creamos la única entidad de nuestra aplicación.Así quedaría la clase:

// Indico que la clase pertenece a la capa de persistencia
// y que es una entidad (objetojava-->tabla)
@Entity
@Table
public class FilesUp implements Serializable { 

    private Long id;
    private String namefile;
    private Date datefile;
    private String pathfile;
    private String typefile;
    private String sizefile;
    private String descripfile;


    // Definimos el id y su comportamiento
    // Genera la clave en orden
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

   
    @Column(name = "nombre", nullable = false, length = 100)
     public String getNamefile() {
        return namefile;
    }

    public void setNamefile(String namefile) {
        this.namefile = namefile;
    }


    @Column(name = "fecha", nullable = false)
    @Temporal(javax.persistence.TemporalType.DATE)
    public Date getDatefile() {
        return datefile;
    }



    public void setDatefile(Date datefile) {
        this.datefile = datefile;
    }


    @Column(name = "ruta", nullable = false)
    public String getPathfile() {
        return pathfile;
    }

    public void setPathfile(String pathfile) {
        this.pathfile = pathfile;
    }

    @Column(name = "sizefile", nullable = false)
    public String getSizefile() {
        return sizefile;
    }

    public void setSizefile(String sizefile) {
        this.sizefile = sizefile;
    }

    @Column(name = "tipefile", nullable = false)
    public String getTypefile() {
        return typefile;
    }

    public void setTypefile(String typefile) {
        this.typefile = typefile;
    }

     @Column(name = "descripcion", nullable = true, length = 200)
    public String getDescripfile() {
        return descripfile;
    }

    public void setDescripfile(String descripfile) {
        this.descripfile = descripfile;
    }

}


De la clase hay que destacar el uso de anotaciones que serviran ha Hibernate
para saber que el objeto es una entidad,cual es el id de la entidad,que este id
sera generado por la base de datos y cual serán los nombres y algunas otras
propiedades básicas para las columnas.

5.2 El DAO

Primero definimos una interface,de esta manera en un futuro podríamos
cambiar la implementación en caso de utilizar otro motor de persistencia distinto a Hibernate.

public interface FilesUpIntDao {

    //Metodo que graba o modifica un registro de la base de datos
    public void guardar(Object entity);

    // Metodo que recupara todos los registros de base datos
     public List listartodos();
  }

Continuamos implementando el DAO.

public class FilesUpDao implements FilesUpIntDao{

   private Session sesion;
   private Transaction tx;

    // Metodo que guarda o modifica el object pasado como parametro
    public void guardar(Object entity) {
        try
        {
            iniciaOperacion();
            sesion.saveOrUpdate(entity);
            tx.commit();
        }catch(HibernateException sf)
        {
            manejaExcepcion(sf);
            throw sf;
        }finally
        {
            sesion.close();
        }

    }

    // Metodo que devuelve todos los registros de la tabla fileup
     public  List listartodos() {
         List filesUp = null;
         try {
            iniciaOperacion();
            Query q = sesion.createQuery("from FilesUp");
            filesUp = (List) q.list();

         }catch(HibernateException sf){
            manejaExcepcion(sf);
            throw sf;
         }
         finally
         {
            sesion.close();
         }
        
         return filesUp;
     }

     
      // Metodo encargado de incializar el SessionFactory y abrir una Tx
   private void iniciaOperacion() throws HibernateException
   {
       // Recuperamos el SessionFactuy y comenzamos las tx
       sesion = HibernateUtil.getSessionFactory().openSession();
       tx = sesion.beginTransaction();
   }

   // Metodo encargado de recoger la excepcion y hacer el rollbak de la transacion
   private void manejaExcepcion(HibernateException sf) throws HibernateException
    {
         tx.rollback();
         throw new HibernateException("Ocurrió un error en la capa de acceso a datos", sf);
    }


}


Como podemos ver se trata de una implementación sencilla ya que solo necesitamos
dos operaciones básicas para cubrir la funcionalidad de nuestra aplicación:

  • 1.Insertar y modifcar datos de lo que se encargará el método guardar().
  • 2.Recuperar información de lo que se encargará el método listartodos()

Vemos que de una manera rápida hemos creado nuestra capa de persistencia teniendo
la ventaja de que trabajando de esta manera podremos decirle ha Hibernate en su
fichero de configuración que sea el mismo el que cree las tablas correspondientes en
base de datos a partir de las clases definidas como entidades persistentes.

6. Capa de Negocio.

Como hemos visto anteriormente la funcionalidad de nuestra aplicación es muy sencilla
por lo que nuestra lógica de negocio también lo será.En realidad en esta clase
solo estamos delegando el control al DAO para que realice la operación correspondiente.

  public class FilesUpManager {

    private FilesUpDao dao;

    public void guardar(FilesUp file){
        dao=new FilesUpDao();
        dao.guardar(file);
    }

     public List getFilesUp() {
        dao=new FilesUpDao();
        final List list = dao.listartodos();
        return list;
    }

  }

7. Capa de Control.

Aquí es donde JSF entra a formar parte de nuestra aplicación.

Esta capa es la encargada de gestionar la comunicación entre la presentación y
la lógica de negocio ,gestionando los eventos provocados por el usuario al realizar
distintas acciones (pulsar un botón,cambios de valores,seleccionar una opción …).
y ejecutando código java para responder a cada una de las acciones.

Las clases que formaran parte de la capa de control son los denomidados
managed-bean de JSF.En nuestro caso,al tener dos pantallas definiremos dos
managed-bean,uno para cada pantalla.

Mas adelante veremos que para que JSF sepa que estas clases forman parte de
la capa de control hemos de definirlas en el faces-config.xml .

Para la pantalla con el listado de ficheros:

public class ListFilesUp {

  

    private FilesUpManager filesUpMgr;
    private List listFiles;
   
    


    // Metodo de control para definir el data table

    public ListFilesUp() {}
    

    
    public List getListFiles() {
        filesUpMgr=new FilesUpManager();
        listFiles=filesUpMgr.getFilesUp();
        return listFiles;
    }

    public void setListFiles(List listFiles) {
        this.listFiles = listFiles;
    }



     
}

En este managed-bean la implementación es muy sencilla ya que solo nos servirá
para mostrar la lista con todos los registros de nuestra tabla en base de datos.

public class EditFilesUp {

    private Long id;
    private String nombre;
    private Date fecha;
    private String ruta;
    private String tipoFile;
    private String sizeFile;
    private String descripfile;

    private FilesUpManager filesUpMgr;
    private FilesUp filesUp ;
    // file upload completed percent (Progress)
    private int fileProgress;
    private UIData componentDataTable;
    private boolean disabledGuardar;
    private boolean disabledUpload;
   


    public EditFilesUp() {}

    //Metodo de navegacion a la pantalla de de edicion
    public String insertFilesUp(){

        // Obtenemos la fecha del sitema
         Calendar fechaActual=new GregorianCalendar();

         // Inicializamos propiedades del backBeans
         this.id=null;
         this.nombre="";
         this.ruta="";
         this.tipoFile="";
         this.sizeFile="0 B";
         this.descripfile="";
         this.fecha=fechaActual.getTime();
         this.fileProgress=0;
         this.disabledGuardar=true;
         this.disabledUpload=false;
         return "insertFilesUp";
     }


    // metodo que inserta o modifica y navega a la pagina inicial de listado
    public String save(){

        filesUpMgr=new FilesUpManager();
        filesUp=new FilesUp();


        if (this.id==null){
            // Insertamos registro
            filesUp.setNamefile(nombre);
            filesUp.setDatefile(fecha);
            filesUp.setPathfile(ruta);
            filesUp.setSizefile(sizeFile);
            filesUp.setTypefile(tipoFile);
            filesUp.setDescripfile(descripfile);
        
        }else{
            // Modificamos registro
            filesUp.setId(id);
            filesUp.setNamefile(nombre);
            filesUp.setDatefile(fecha);
            filesUp.setPathfile(ruta);
            filesUp.setSizefile(sizeFile);
            filesUp.setTypefile(tipoFile);
            filesUp.setDescripfile(descripfile);
        
        }

        filesUpMgr.guardar(filesUp);
        

        return "home";
    }

    //metodo de navegacion hacia el registro seleccionado
    public String editSelectFile(){

         int index=getComponentDataTable().getRowIndex();
         filesUp = (FilesUp) getComponentDataTable().getRowData();


         this.id=filesUp.getId();
         this.nombre=filesUp.getNamefile();
         this.fecha=filesUp.getDatefile();
         this.ruta=filesUp.getPathfile();
         this.tipoFile=filesUp.getTypefile();
         this.sizeFile=filesUp.getSizefile();
         this.descripfile=filesUp.getDescripfile();
         this.disabledGuardar=false;
         this.disabledUpload=true;
         this.fileProgress=0;


         
         return "editFilesUp";
     }



     // metodo Listener para el uploadFile
     public void cargarFile(ActionEvent event) {
    
       InputFile inputFile = (InputFile) event.getSource();
       File file=inputFile.getFile();
       FileInfo fileInfo = inputFile.getFileInfo();


       if (file!=null){
       this.ruta=file.getPath();
       this.nombre   =fileInfo.getFileName();
       this.tipoFile =fileInfo.getContentType();
       this.sizeFile =Utilidades.getSizeFormatted(fileInfo.getSize()) ;
       this.descripfile="";
       Calendar fechaActual=new GregorianCalendar();
       this.fecha=fechaActual.getTime();
       this.disabledGuardar=false;
       }
    }

     
    // metodo listener para la barra de progreso
     public void fileUploadProgress(EventObject event) {
        InputFile ifile = (InputFile) event.getSource();
        fileProgress = ifile.getFileInfo().getPercent();
        
        
    }



Para la pantalla de edición:

Este managed-bean es el que contiene el control para el resto de las funcionalidades
de nuestra aplicacion.En la capa de presentación veremos como los
componentes ICEfaces lanzan cada uno de los metodos dependiendo de la
accion realizada por el usuario.

Es importante a la hora de implemetar los distintos managed-bean saber los tipos de eventos que maneja JSF:

  • 1. Evento Action:Se produce al activarse el componente que implementa la interface
    ActionSource.Se trata de botones e hiperlinks.
  • 2. Evento Value-change:Se produce al cambiar el dato de un componente UIInput o sus
    subclases.Solo se lanza en caso de haber errores de validación,además el valor del atributo inmediate
    cambia su actuación.
  • 3. Evento Data-Model:Se produce al cambiar la columna seleccionada en un componente de
    tipo UIData.


También es importante saber como trata estos eventos:

  • 1.Implemtando una clase Listener que recoja los eventos y registrando esta en el
    componente que los produce mediante el tag actionListener o valueChangeListener.
  • 2. Implementando un metodo en los managed-bean que sea referenciado desde el componente con una expresion de
    metodo en el atributo apropiado de este.

8. Capa de Presentación.

Para la capa de presentación utilizaremos ICEfaces.Este framework basado en
JSF nos habilita un set de componentes de interfaz de usuario rico y potente.

En este caso en concreto utilizaremos distintos componentes como outputtext,inputtext,
datatable e inputfile.

Pantalla listado:

<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib prefix="ice" uri="http://www.icesoft.com/icefaces/component"%>

    
    
                  
            
              <h:outputText value="#{msg.tituloPagina}"/>
        
        
            
              


De esta página destacaremos:

  • Componente datatable

    • Atributo value:Sirve para indicar al componente el origen de los datos.
    • Atributo binding:Sirve pasa asociar el componente a una propiedad de managed-bean de edición con el fin de porder recuperar la fila seleccionada.
  • Componente commandButton
    • Atributo action:Indicamos el método que se ejecutará al pulsar y que devolverá la navegación de la aplicación.Las
      reglas de navegación las definiremos el el fichero faces-config.xml

Pantalla de edición:

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib prefix="ice" uri="http://www.icesoft.com/icefaces/component"%>

    
    
        
             <h:outputText value="#{msg.tituloPagina}"/>
            
            
        
                
            
                

De esta página destacaremos:

  • Componente inputFile

    • Atributo actionListener:Indicamos que método de control se ejecutará al pulsar el boton de upload
    • Atributo progressListener:Para indicar el método que gestiona la barra de progreso asociada

Para renderizar la barra de progreso utilizamos el componente outputProgress.

9. Configuracion de Hibernate y JSF.

Para configurar Hibernate debemos editar el fichero hibernate.cfg.xml



  

    org.hibernate.dialect.MySQLDialect
    com.mysql.jdbc.Driver
    jdbc:mysql://localhost:3306/testautentia
    root
    root
    1
    true
    create

    
     
    
  



Mediante este fichero estamos indicando a Hibernate todo lo que necesita saber
para integrarse con base de datos.Cabe destacar la propiedad «hibernate.hbm2ddl.auto»
que sirve para que Hibernate cree la tablas al arrancar la aplicación.Opción muy recomendable en desarrollo.

También es importante como indicamos cual van a ser nuestras entidades persistentes
mediante mapping class.

Para la configuraciónn de JSF editamos el fichero faces-config.xml




    
        es
        en
        en_US
        es_ES
    
   MensajesAplicacion

    

    
        listFilesUp
        com.testautentia.control.ListFilesUp
        session
    

    
        editFilesUp
        com.testautentia.control.EditFilesUp
        request
    

    

     
     
         
             home
             /welcomeJSF.jspx
         
     

     
         /welcomeJSF.jspx
         
             insertFilesUp
             /editFilesUp.jspx
         
         
             editFilesUp
             /editFilesUp.jspx
         
     




    


En este fichero definimos nuestros managed-bean y las reglas de navegación de la aplicación.

10. Conclusiones.

Como conclusión podemos decir que los frameworks que hemos utilizado para construir nuestra
aplicación proporcionan una serie de facilidades que hacen que el desarrollo se lleve a cabo de una manera
coherente y estructurada.Además reduciremos el tiempo de desarrollo para la capa de persistencia gracias a Hibernate
,siendo esta facilmente mantenible,nos hemos servido de JSF para diferenciar claramente el control del negocio y nuestra presentación será
mucho mas flexible,dinámica y profesional.

Por lo tanto iniciarse en el uso de estas tegnologías es una opción muy recomendable a la hora de realizar desarrollos web.

Un saludo.

Saul

mailto:sgdiaz@autentia.com

2 COMENTARIOS

  1. muy buen tutorial, pero incompleto, sin el código fuente, es complicado despejar dudas cuando se es principiante ante las tecnologías que allí se presentan, por favor, he visto muchos tutoriales, y todos bueno, pero sin el CÓDIGO FUENTE, no es muy claro tu objetivo, Gracias, por favor, si tu intención es colaborar y ayudar igual a la de todos, agreguen el código fuente, nuevamente, Gracias.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad