Desarrollo WEB.


Las practicas de programación orientadas a la web son muy cambiantes en el tiempo. Es necesario conocer e implementar tecnologías, conocer lenguajes,integrar comunidades,usar Ides, etc, recientes, para responder al mercado que se acerca.

Mostrando entradas con la etiqueta primefaces. Mostrar todas las entradas
Mostrando entradas con la etiqueta primefaces. Mostrar todas las entradas

lunes, 19 de agosto de 2013

Pasar parámetros desde cliente javascript a JSF

En ocasiones se hace necesario llevar desde nuestra capa de presentacion, valores de javascript a un controlador jsf y de una a un xhtml, lo importante aca no es como se hace llegar sino como se captura, se puede enviar mediante ajax, mediante una url, etc.

Con las nuevas actualizaciones de JSF 2.0 se puede hacer de una manera muy fácil.
  •  Enviar el parametro por url
  • Código en el .xhtml que espera el parámetro y muestra.
  • Código en el controlador que recoge y envia al .xhtml

Aplicación movil con primefaces, JSF, EJB y postgres

Cuando me encontré con la necesidad laboral de realizar una aplicación móvil según  requerimiento del sistema ERP que venimos desarrollando hace dos años, para una empresa multinacional en Panamá  empece a investigar a fondo cual seria la opción mas viable para integrar mecanismos de software para móviles que nos permitiera tomar parte de la lógica del negocio ya existente (EJB) , con un costo computacional bajo, tecnología multiplataforma y orientado a la web, tome la decision de usar los recursos de primefaces mobile.

Estas fueron mis opciones:

  • Opción 1: Aplicación móvil para Android
Tenia todos los recursos para conectividad con postgres, recursos gráficos y demás componentes del jdk de android, plataforma de desarrollo integrada en netbeans, ágil y fácil de instalar, pero a la hora de pensar en ¿si todos mis usuarios tendría android?, se callo en el dilema multiplataforma, pailas no había nada que hacer con android, muy bonito y todo, fácil de programar, pero nada que hacer a la hora de requerir sistema operativo especifico.
 
  • Opción 2: Aplicación web para móviles en Primefaces Mobile.
Con primefaces mobil tenia la útil herramienta que me brindaba componentes fáciles de integrar con mis controladores de sesión ya existentes, ademas me permitía usar como librería mi componente principal en la aplicación grande (ERP), Primefaces es un framework para aplicaciones web integrado con xhtml (JSF 2), su evolución es constante y posee una gran comunidad de foristas y blogeros
  • Opción 3: Windows móvil
Esta si que ni mente le gaste, iba a ser igual a la primera opción.

Definitivamente me quedaría con la opción 2, por ser la mas atractiva a cumplir mi requerimiento de multiplataforma, solo se necesitaría un navegador web para usar la interfaz y como todo SO en la actualidad tiene sus navegadores afines, entonces empece a desarrollar este cuento, después de esta historia les comparto la técnica y los recursos para que monten sus app móviles de manera rápida y oportuna.

  1. Librería primefaces mobile.
    1. Descargar la libreria de la pagina oficial del proyecto primefaces.org
  2. Themes
    1. no se requiere agregar libreria del tema visual pues  ya viene con uno por defecto
  3. Configuracion
    1.  en el archivo web xml ...
  4. Entidades ...
  5. Interfaces ...
  6. Controladores ...
  7. Vistas(xhtml) ...
 Imagenes.










domingo, 11 de agosto de 2013

Upload de archivos en una aplicación web con JSF 2.0

Upload con JSF 2.0
  • Carpeta destino
Es importante tener una carpeta definida en el contexto de la aplicación para crear los archivos subidos por el recurso java de fileupload y primefaces en jsf 2.0
nuestro directorio destino se encuentra en /modulos/rh/rhEmpleadoFoto/fotos

  • En el .xhtml

<h:form enctype="multipart/form-data" id="formfileupload" prependid="false">
     <!--aca neustro componente se ejecuta automaticamente apenas recibe el archivo-->
            <p:fileupload actualiza="" allowtypes="/(\.|\/)(gif|jpe?g|png)$/" auto="true" cancellabel="Cancelar" componente="" donde="" dragdropsupport="true" fileuploadlistener="#{rhEmpleadoFotoController.accionFileUpload}" foto="" grafico="" id="fileupload" imagen="" la="" label="Seleccionar" mi="" mode="advanced" rendered="true" renderiza="" se="" sizelimit="1000000" update=":formpersonal:idRhEmpleadoFoto" uploadlabel="Subir al servidor" xhtml="">
            </p:fileupload> 
            <!--
  para tener donde visualizar la imagen despues de ingresarse.
                El nombre en el contexto de la aplicacion para mi controlador es rhEmpleadoFotoController 
                -->
        <p:graphicimage cache="false" height="300" id="imagemTmp" style="margin: 0 auto;" value="#{rhEmpleadoFotoController.imagem}">
</p:graphicimage></h:form>
En nuestro xhtml ingresamos el anterior codigo, lo adaptamos de acuerdo al framework que estemos usando en mi caso primefaces.
  • Controlador
En el cuerpo de mi controlador ingreso estas funciones teniendo en cuenta que algunas propiedades se deben declarar como privadas en el controlador y se les debe crear métodos accesores y colocadores para que sean accedidos desde otros ámbitos de la aplicación en las .xhtml(UI)
    
public void accionFileUpload(FileUploadEvent event) { //evento propio del framework
        try {
            file = event.getFile();
            byte[] foto = event.getFile().getContents();
            String nomeArquivo = event.getFile().getFileName();
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ServletContext scontext = (ServletContext) facesContext.getExternalContext().getContext();
            String archivo = scontext.getRealPath("/modulos/rh/rhEmpleadoFoto/fotos/" + nomeArquivo); //guardar en ruta basica para luego mover
            crearArchivo(foto, archivo);
            imagem = new DefaultStreamedContent(event.getFile().getInputstream()); //agregar geter y seter para poder ser accedida desde otros xhtml
            
            selectedEntidad = new RhEmpleadoFoto(); //entidad para persistir en la base de datos
            selectedEntidad.setNombre(nomeArquivo);
            selectedEntidad.setIdRhEmpleado(idRhEmpleado);
            long peso = event.getFile().getSize();
            int x = (int) peso;
            selectedEntidad.setPeso(x);
            selectedEntidad.setRuta("/modulos/rh/rhEmpleadoFoto/fotos");
            selectedEntidad.setLlaveUnica(GenerarRandom().toString());
            selectedEntidad.setEstadoEliminado(Boolean.FALSE);
            getFacade().create(selectedEntidad); //crea el objeto(RhEmpleadoFoto) en la bd

     //dos objetos para hacer renombrado de archivo y copiado a carpetas
            RhEmpleadoFoto current = ejbFacade.findObjeto(selectedEntidad);
            RhEmpleadoFoto current2 = new RhEmpleadoFoto();
            RhEmpleadoFoto current2 = ejbFacade.findObjeto(selectedEntidad);
            
            
            if (renombrarArchivo(current2.getRuta() + "/" + current2.getNombre(), current2.getRuta() + "/" + (idRhEmpleado.getIdRhEmpleado() + ""))) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Mensaje:", "Ingreso Exitoso"));
            } else {
                if (renombrarArchivo(current2.getRuta() + "/" + current2.getNombre(), current2.getRuta() + "/" + (idRhEmpleado.getIdRhEmpleado() + ""))) {
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Mensaje:", "Ingreso Exitoso")); //para enviar el mensaje a la growl del framework
                } else {
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Mensaje:", "" + current2.getRuta() + "/" + current2.getNombre() + " " + current2.getRuta()));
                }
            }

            recreateModel();
            FacesMessage msg = new FacesMessage("Succesful", file.getFileName() + " Fue Cargado Exitosamente.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
            //cerrarPanelFoto(); //una funcion booleana para renderizar el contenido en el xhtml de acuerdo a lo sucedido
        } catch (Exception ex) {
            Logger.getLogger(IngenieriaProductoImagenController.class.getName()).log(Level.SEVERE, null, ex.getMessage());
            FacesMessage msg = new FacesMessage("Succesful", file.getFileName() + " Error en la carga:" + ex.getMessage());
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }
    
     /**
     * Funcion para mover y renombrar un archivo
     *
     * @param String archivo Archivo o directorio a renombrar
     * @param String directorio Directorio destino
     * @exception RCException Se genera una excepción genérica.
     * @return boolean
     */
    public boolean renombrarArchivo(String archivo, String directorio) {
        try {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ServletContext scontext = (ServletContext) facesContext.getExternalContext().getContext();
            String Sarchivo = scontext.getRealPath(archivo);
            File archivos = new File(Sarchivo);
            String Sdirectorio = scontext.getRealPath(directorio);
            File dir = new File(Sdirectorio);
            String name = archivos.getName();
            int j = name.indexOf(".");
            String newname = "" + GenerarRandom() + "" + name.substring(j, name.length());
            boolean semovio = archivos.renameTo(new File(dir, newname));
            if (!semovio) {
                System.out.print("El archivo no se ha Movido ...");
                return false;
            } else {
                current.setNombre(newname);
                current.setRuta("/modulos/rh/rhEmpleadoFoto/fotos/" + idRhEmpleado.getIdRhEmpleado()); //una carpeta con el id del objeto que lo contiene, en mi caso empleado
                ejbFacade.edit(current);
                System.out.print("Se Movio ...");
                return true;
            }
        } catch (Exception e) {
            System.out.print("" + e.getMessage());
            return false;
        }
    }

     /**
     * Funcion para crear un archivo
     *
     * @param byte[] bytes objeto
     * @param String archivo archivo
     * @exception RCException Se genera una excepción genérica.
     * @return void
     */
    
    public void crearArchivo(byte[] bytes, String archivo) {
        FileOutputStream fos;
        try {
            fos = new FileOutputStream(archivo);
            fos.write(bytes);
            fos.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(IngenieriaProductoImagenController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(IngenieriaProductoImagenController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
  • Web.xml
Anexar estas lineas al archivo de configuración de la aplicación web, pero depende del framework usado, en mi caso primefaces.
   <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class> //de mi framework
        <init-param>
            <param-name>thresholdSize</param->
<!--tamaño maximo de los archivos para el contexto de la aplicacion-->
            <param-value>512000</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    <filter>
        <mime-mapping>
        <extension>png</extension>
        <mime-type>image/png</mime-type>
    </mime-mapping>
  •  Librerías 
 usar la librería commons-fileupload-1.2.2.jar y sus librerías dependientes

 Para una opcion mas clara en lenguaje nativo descargue este ejemplo. >>

lunes, 8 de abril de 2013

Lenguaje de Expresión en una pagina .xhtml en JSF

Usando primefaces muchas veces necesitamos renderizar o habilitar un componente, para ello requerimos en ocasiones usar EL(lenguaje de expresión)  en el interior de una propiedad del componente, esta propiedad se encuentra siempre sobre un archivo .xhtml. 

Estas son algunas de las opciones.

  • rendered="#{empty comprasOrdenController.selected.comprasOrdenDetallesList ? true : false}"
  • disabled="#{comprasOrdenController.actualizar eq 'si' ? true : false}"
  • value="#{comprasOrdenController.isHabilitado eq true ? 'SI' : 'NO'}"
  • value="#{itemt.idInventarioItem.codigoItem eq null ? '': itemt.idInventarioItem.codigoItem}"

jueves, 28 de marzo de 2013

Primefaces y su evolución.!

En noviembre del 2011 conocí primefaces, y empecé de lleno en producción con él, un framework que va de maravilla con las aplicaciones web realizadas en JSF (java server faces), es muy fácil de implementar y sobre todo muy hermoso y con una documentación excelente, tiene infinidad de componentes visuales que se integran con controladores java, esto hace que la programación orientada a la web sea muy eficiente, sobre todo que su mantenimiento sea muy fácil y agradable para cualquier desarrollador de nuevas tecnologías.

Pero como todo lo bueno tiene su evolución, primefaces no es la excepción, cuando inicie, fue con la versión 3.0, ahora vamos en la 3.5, claro que aun estoy en la 3.4 debido a que los cambios en la 3.5 son muy críticos y se necesita mucho tiempo para realizar ajustes en los códigos.

Estas son algunas de las adaptaciones que se deben realizar para migrar a la versión 3.4
  • Diferenciar entre valores de la propiedad id y valores de propiedad widgetVar, deben ser diferentes.
  • Los selects con filtros deben tener altura (height)
  • Los selects normales deben tener  style="min-width: 120px;", es decir un ancho mínimo.
  • ... entre otros que iré colocando poco a poco a medida que me valla acordando.
Todavía no hay mucha eficiencia en los filtros de tablas cuando se trata de grandes cantidades de datos, pero con un poco de astucia indígena se pueden realizar filtros personalizados para búsquedas óptimas. 

El framework es libre pero con un poco de dinero se puede obtener una versión pro (licenciada) donde el soporte es su mayor fortaleza.

Muchas técnicas se van aprendiendo con el uso diario del framework, la idea es optar por uno y aprender a usarlo bien, con eso podemos brindar a nuestras empresas una herramienta segura para implementar aplicaciones java web empresariales o bien llamadas J2EE.

Para los iniciados en primefaces les recomiendo suscribirse al foro, la comunidad de primefaces es grande y hay moderadores del foro con prime que son unos excelentes colaboradores.