Foros del Web » Programación para mayores de 30 ;) » Java »

[SOLUCIONADO] JSF - FileUpload

Estas en el tema de JSF - FileUpload en el foro de Java en Foros del Web. Saludos a todos señores, soy nuevo, estoy trabajando con Primefaces, hibernate y maven, tengo una tabla vendedores y esta tiene un campo imagen que es ...
  #1 (permalink)  
Antiguo 13/12/2014, 12:17
 
Fecha de Ingreso: diciembre-2014
Ubicación: Lima
Mensajes: 68
Antigüedad: 9 años, 4 meses
Puntos: 0
JSF - FileUpload

Saludos a todos señores, soy nuevo, estoy trabajando con Primefaces, hibernate y maven, tengo una tabla vendedores y esta tiene un campo imagen que es de tipo string, pues lo que quiero hacer es guardar el nombre de la imagen y subir esa imagen al servidor el cual es la carpeta del proyecto.Ya pude mostrar el fileUpload, configuré el faces-config y el web xml, ya estan las dependencias en el pom.xml.
Pero cuando le doy guardar, me guarda todos los registros pero no el nombre de la imagen, lo primero que quiero hacer es guardar el nombre, luego de eso, intentare subir la imagen.

adjunto las lineas del fileupload

Código HTML:
Ver original
  1. <p:dialog id="fileUpload" header="#{msgs.form_imagen}" widgetVar="fileDialogWidget">
  2.     <p:fileUpload fileUploadListener="#{vendedorBean.handleFileUpload}" mode="advanced" dragDropSupport="false"  
  3. sizeLimit="20480" fileLimit="1" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" oncomplete="PF('fileDialogWidget').hide()"
  4. uploadLabel="Subir Imagen" cancelLabel="Cancelar" label="Elegir" update="imagenG" />
  5.     <p:graphicImage id="imagenG" value="#{vendedorBean.unVendedor.venImagen}" />                               
  6. </p:dialog>
y el bean

Código Java:
Ver original
  1. public void handleFileUpload(FileUploadEvent event) {
  2.         file = event.getFile();
  3.         try {
  4.             byData = IOUtils.toByteArray(file.getInputstream());
  5.         } catch (IOException e) {
  6.             e.printStackTrace();
  7.         }
  8.     }

Se abre un dialog para escoger la imagen.

Ya funciona el boton subir, cuando le hago clic la barra hace el efecto de cargar.
La estructura de mi proyecto es para la parte web
-src>
-main>
-webapp>
-imgVendedor>img.jpg
....webapp>views>vendedor>nuevo.xhtml

Lo que deseo es subir la imagen a imgVendedor, y guardar el nombre en la bd como mencione anteriormente.

estoy usando
VendedorDao
VendedorDaoIpl --> para guardar me retorna un boolean
y VendedorBean

Espero se haya entendido, si puedo subir una imagen, pudeo subir cualquier cosa....gracias de antemano
  #2 (permalink)  
Antiguo 13/12/2014, 21:55
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: JSF - FileUpload

Hola,

Posiblemente, tendrías que guardar el nombre del archivo que se subió en alguna variable temporalmente, para que a la hora de guardar tengas esos datos disponibles.

Código:
public void handleFileUpload(FileUploadEvent event) {
		file = event.getFile();
		setVenImagen(file.getFilename());
		try {
			byData = IOUtils.toByteArray(file.getInputstream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
En ese momento ya tienes el nombre del archivo en venImagen (posiblemente, si el navegador envió el nombre).

Ahora, como siempre en el caso de JEE y principalmente JSF, si no se tiene toda la información sobre el problema es difícil saber con exactitud que es lo que tienes que hacer después.

Por ejemplo, si el ManagedBean es de Sesión, entonces ya no tienes que hacer nada mas, si es de Request, tendrás que poner ese valor en un <p:inputHidden> para que JSF después lo recoja en venImagen al hacer el POST.

Código HTML:
Ver original
  1. <p:dialog id="fileUpload" header="#{msgs.form_imagen}" widgetVar="fileDialogWidget">
  2.     <p:fileUpload fileUploadListener="#{vendedorBean.handleFileUpload}" mode="advanced" dragDropSupport="false"  
  3. sizeLimit="20480" fileLimit="1" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" oncomplete="PF('fileDialogWidget').hide()"
  4. uploadLabel="Subir Imagen" cancelLabel="Cancelar" label="Elegir" update="imagenG" />
  5.     <p:graphicImage id="imagenG" value="#{vendedorBean.unVendedor.venImagen}" />                               
  6. </p:dialog>

Adicionalmente, esa parte es confusa, después de que cargas la imágen, actualizas imagenG pero lo ocultas, y adicionalmente tienes que observar que al usar graphicImage no se envía con el POST, porque es renderizado como un <img>, solamente sería un 'visual clue', aunque lo ocultas inmediatamente.

Saludos,
  #3 (permalink)  
Antiguo 15/12/2014, 11:21
 
Fecha de Ingreso: diciembre-2014
Ubicación: Lima
Mensajes: 68
Antigüedad: 9 años, 4 meses
Puntos: 0
Respuesta: JSF - FileUpload

Cita:
Iniciado por HackmanC Ver Mensaje
Hola,

Posiblemente, tendrías que guardar el nombre del archivo que se subió en alguna variable temporalmente, para que a la hora de guardar tengas esos datos disponibles.

Código:
public void handleFileUpload(FileUploadEvent event) {
		file = event.getFile();
		setVenImagen(file.getFilename());
		try {
			byData = IOUtils.toByteArray(file.getInputstream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
En ese momento ya tienes el nombre del archivo en venImagen (posiblemente, si el navegador envió el nombre).

Ahora, como siempre en el caso de JEE y principalmente JSF, si no se tiene toda la información sobre el problema es difícil saber con exactitud que es lo que tienes que hacer después.

Por ejemplo, si el ManagedBean es de Sesión, entonces ya no tienes que hacer nada mas, si es de Request, tendrás que poner ese valor en un <p:inputHidden> para que JSF después lo recoja en venImagen al hacer el POST.

Código HTML:
Ver original
  1. <p:dialog id="fileUpload" header="#{msgs.form_imagen}" widgetVar="fileDialogWidget">
  2.     <p:fileUpload fileUploadListener="#{vendedorBean.handleFileUpload}" mode="advanced" dragDropSupport="false"  
  3. sizeLimit="20480" fileLimit="1" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" oncomplete="PF('fileDialogWidget').hide()"
  4. uploadLabel="Subir Imagen" cancelLabel="Cancelar" label="Elegir" update="imagenG" />
  5.     <p:graphicImage id="imagenG" value="#{vendedorBean.unVendedor.venImagen}" />                               
  6. </p:dialog>

Adicionalmente, esa parte es confusa, después de que cargas la imágen, actualizas imagenG pero lo ocultas, y adicionalmente tienes que observar que al usar graphicImage no se envía con el POST, porque es renderizado como un <img>, solamente sería un 'visual clue', aunque lo ocultas inmediatamente.

Saludos,
Muchas gracias HackmanC, me funciono lo de agregar esa linea, y seteo el nombre de la imagen en un campo oculto, ya pude guardar el nombre de la imagen en la bd, ahora solo me falta guardar o copiar la imagen al servidor, el cual es la carpeta del proyecto en la carpeta imgVendedor.
Y repondiendo a lo ultimo, yo presionaba un boton y me abria un dialog donde seleccionaba la imagen a guardar, luego al presionar subir, el cuadro de dialogo desaparecia para poder guardar el registro, pero le quite esa opcion para que directo se abra

Al final quedo asi, para escoger la imagen es desde una pestaña
Código HTML:
Ver original
  1. <p:tab title="#{msgs.pImagen}">
  2. <h:panelGrid columns="1" cellpadding="5" id="panelImagen" >
  3. <p:graphicImage id="imagenG2" value="/imgEmpleados/#{vendedorBean.unVendedor.venImagen}"/>
  4. <h:outputLabel value="#{msgs.form_imagen}" />
  5. <p:fileUpload fileUploadListener="#{vendedorBean.handleFileUpload}" mode="advanced" dragDropSupport="false"
  6.   sizeLimit="20480" fileLimit="1" allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
  7.      uploadLabel="Subir Imagen" cancelLabel="Cancelar" label="Elegir" update="imagenG" />
  8. <p:graphicImage id="imagen"  value="#{vendedorBean.unVendedor.venImagen}" />   
  9. <p:inputText id="imagenG"  value="#{vendedorBean.unVendedor.venImagen}" /> 
  10. </h:panelGrid>
  11. </p:tab>
mi pregunta ahora es si me das una pista de como llevar la imagen al servidor, a la carpeta imgEmpleados como se muestra en el primer <p:graphicImage
De nuevo muchas gracias.
  #4 (permalink)  
Antiguo 15/12/2014, 12:34
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: JSF - FileUpload

Hola,

Cita:
Iniciado por jelastic Ver Mensaje
... ya pude guardar el nombre de la imagen en la bd, ahora solo me falta guardar o copiar la imagen al servidor, el cual es la carpeta del proyecto en la carpeta imgVendedor.
...
mi pregunta ahora es si me das una pista de como llevar la imagen al servidor, a la carpeta imgEmpleados como se muestra en el primer <p:graphicImage
...
Esa parte es simplemente guardar lo que tienes en byData en un archivo. Técnicamente hay demasiadas formas de guardar un archivo que viene de un InputStream en un OutputStream.

Código:
public void handleFileUpload(FileUploadEvent event) {
		file = event.getFile();
		try {
			byData = IOUtils.toByteArray(file.getInputstream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
Leer todo el ByteArray en memoria normalmente no es buena idea, (va a ocupar la misma cantidad de bytes en memoria RAM del tamaño original del archivo). Como estás usando Apache IO revisa en la documentación de esa librería que cuenta con un montón de métodos para leer, escribir y copiar archivos.

Para obtener el nombre de la carpeta destino podrías probar a usar:
Código:
FacesContext.getCurrentInstance().getExternalContext().getRealPath("/")...
Pero no estoy completamente seguro que funcione bien.

Un detalle adicional que posiblemente tendrías que tomar en cuenta es cambiarle de nombre al archivo final y guardar ese nombre en la base de datos, y solamente guardas el nombre del archivo original en la base de datos como referencia. Por los motivos lógicos como nombre duplicados, caracteres extendidos, etc. El nombre de archivo "Pruebas:Dos.jpg" en Windows no va a funcionar como posiblemente puedas creer inicialmente, aunque es un nombre completamente válido en Unix.

Saludos,
  #5 (permalink)  
Antiguo 15/12/2014, 23:10
 
Fecha de Ingreso: diciembre-2014
Ubicación: Lima
Mensajes: 68
Antigüedad: 9 años, 4 meses
Puntos: 0
Respuesta: JSF - FileUpload

Cita:
Iniciado por HackmanC Ver Mensaje

Para obtener el nombre de la carpeta destino podrías probar a usar:
Código:
FacesContext.getCurrentInstance().getExternalContext().getRealPath("/")...
Pero no estoy completamente seguro que funcione bien.

Un detalle adicional que posiblemente tendrías que tomar en cuenta es cambiarle de nombre al archivo final y guardar ese nombre en la base de datos, y solamente guardas el nombre del archivo original en la base de datos como referencia. Por los motivos lógicos como nombre duplicados, caracteres extendidos, etc. El nombre de archivo "Pruebas:Dos.jpg" en Windows no va a funcionar como posiblemente puedas creer inicialmente, aunque es un nombre completamente válido en Unix.

Saludos,
Gracias nuevamente HackmanC, estuve intentando y pude enviar la imagen al servidor con estas lineas de codigo:

Código HTML:
Ver original
  1. public void subirImagen() throws IOException {
  2.         InputStream inputStream = null;
  3.         OutputStream outputStream = null;
  4.         VendedorDao vendedorDao = new VendedorDaoImpl();
  5.         int cod = vendedorDao.getId();
  6.         try {
  7.             ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
  8.             String path = (String) servletContext.getRealPath("/imgEmpleados");
  9.             outputStream = new FileOutputStream(new File(path + "/" + cod + ".jpg"));
  10.             inputStream = this.file.getInputstream();
  11.             int read = 0;
  12.             byte[] bytes = new byte[1024];
  13.             while((read=inputStream.read(bytes)) != -1) {
  14.                 outputStream.write(bytes, 0, read);
  15.             }
  16.             System.out.println("Imagen Subida Correctamente al Servidor en : "+path);
  17.         } catch (Exception e) {
  18.             System.out.println("No se pudo subir la imagen " + e.toString());
  19.         } finally {
  20.             if(inputStream != null) {
  21.                 inputStream.close();
  22.             }
  23.             if(outputStream != null) {
  24.                 outputStream.close();
  25.             }
  26.         }
  27.     }
Este metodo lo llamo en el handleFileUpload().
Pero no me guarda en la carpeta que yo quiero sino en otra que es esta :
C:\Users\Jonathan\workpaceL\.metadata\.plugins\org .eclipse.wst.server.core\tmp2\wtpwebapps\Ferrerter iaWeb\imgEmpleados
y yo quiero que me guarde aqui: C:\Users\Jonathan\workpaceL\FerrerteriaWeb\src\mai n\webapp\imgEmpleados
que se me puede estar escapando, quizas falte algo.
Gracias.
  #6 (permalink)  
Antiguo 16/12/2014, 20:44
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: JSF - FileUpload

Hola,

Cita:
Iniciado por jelastic Ver Mensaje
...Pero no me guarda en la carpeta que yo quiero sino en otra que es esta :
C:\Users\Jonathan\workpaceL\.metadata\.plugins\org .eclipse.wst.server.core\tmp2\wtpwebapps\Ferrerter iaWeb\imgEmpleados
y yo quiero que me guarde aqui: C:\Users\Jonathan\workpaceL\FerrerteriaWeb\src\mai n\webapp\imgEmpleados
...
No estoy seguro si comprendes bien la diferencia entre esas dos rutas, la primera es la ruta donde está corriendo el servidor de aplicaciones de 'pruebas' dentro de Eclipse, al final si haces un deploy del WAR/EAR en el servidor no va a guardarlo en esa ruta, sino en otra diferente relativa al root de tu aplicación.

Ahora en el segundo caso no tiene sentido, no puedes guardar las imágenes dentro de esa carpeta porque ese es el proyecto donde estás trabajando, no va a ser la ruta donde va a correr tu aplicación. Si lo guardar allí va a ser incluido dentro del WAR o EAR que construyas con eclipse.

Como indiqué, en la primera ubicación no va a ser esa al final dentro de tu servidor, tendrías que hacer un deploy para ver donde va a guardar las imágenes realmente en el servidor real, no el de pruebas.

Así que, yo no sabría como encontrar esa ubicación en tiempo de ejecución de la aplicación, aunque de lo que estoy casi seguro es que no hay ninguna clase que haga referencia a esa ubicación. Podrías usar rutas absolutas si realmente tu intención es guardarlo en esa ubicación por algún motivo desconocido.

Saludos,
  #7 (permalink)  
Antiguo 16/12/2014, 21:23
 
Fecha de Ingreso: diciembre-2014
Ubicación: Lima
Mensajes: 68
Antigüedad: 9 años, 4 meses
Puntos: 0
Respuesta: JSF - FileUpload

Cita:
Iniciado por HackmanC Ver Mensaje
Hola,



No estoy seguro si comprendes bien la diferencia entre esas dos rutas, la primera es la ruta donde está corriendo el servidor de aplicaciones de 'pruebas' dentro de Eclipse, al final si haces un deploy del WAR/EAR en el servidor no va a guardarlo en esa ruta, sino en otra diferente relativa al root de tu aplicación.

Ahora en el segundo caso no tiene sentido, no puedes guardar las imágenes dentro de esa carpeta porque ese es el proyecto donde estás trabajando, no va a ser la ruta donde va a correr tu aplicación. Si lo guardar allí va a ser incluido dentro del WAR o EAR que construyas con eclipse.

Como indiqué, en la primera ubicación no va a ser esa al final dentro de tu servidor, tendrías que hacer un deploy para ver donde va a guardar las imágenes realmente en el servidor real, no el de pruebas.

Así que, yo no sabría como encontrar esa ubicación en tiempo de ejecución de la aplicación, aunque de lo que estoy casi seguro es que no hay ninguna clase que haga referencia a esa ubicación. Podrías usar rutas absolutas si realmente tu intención es guardarlo en esa ubicación por algún motivo desconocido.

Saludos,
Hola, gracias, estuve investigando sobre eso, yo puse las imagenes en la carpeta dentro del proyecto, pues desde ahi las llamo para mostrarlas luego al hacer la consulta, del mismo modo que la pagina de primefaces, desde un comienzo no me gusto eso, pero bueno yo para consultar y llenar los campos para la edicion, lo hago en dos paginas diferentes, en una tengo mi lista con mis vendedores, y otra donde esta mi formulario, el formulario lo lleno con un bean, el fragmento de codigo es este:
Código Java:
Ver original
  1. public String buscar(ActionEvent event) {
  2.         this.unVendedor.setVenCodigo(unVendedor.getVenCodigo());
  3.         return "/views/vendedores/editar";
  4.     }

con eso llamo a mi otra hoja llamada editar.xhtml y lleno los campos, junto con la imagen el cual tienen este codigo :
Código HTML:
Ver original
  1. <p:graphicImage id="imagen" value="/imgEmpleados/#{vendedorBean.unVendedor.venImagen}"/>

habra alguna forma de mostrar la imagen del servidor y no la que esta en el proyecto, no encontre nada parecido este dia, y ahi me quedé.
Gracias
  #8 (permalink)  
Antiguo 16/12/2014, 22:27
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: JSF - FileUpload

Hola,

Cita:
Iniciado por jelastic Ver Mensaje
Código HTML:
Ver original
  1. <p:graphicImage id="imagen" value="/imgEmpleados/#{vendedorBean.unVendedor.venImagen}"/>
Allí ya las cosas se pusieron un poco confusas, si subiste la imagen en la ubicación que indicaste anteriormente, el directorio wtpwebapps. Con este código que muestras debería aparecer la imagen correctamente, sin importar si está en pruebas o es el servidor real, porque es 'relativa'. Por ese motivo fue que usaste el método getRealPath().

Cita:
Iniciado por jelastic Ver Mensaje
...habra alguna forma de mostrar la imagen del servidor y no la que esta en el proyecto, no encontre nada parecido este dia, y ahi me quedé. ...
Primero que todo, tienes que tomar en cuenta que aunque Eclipse guarda los proyectos por defecto en el Workspace, no debería ser así; principalmente porque resulta confuso en algunos casos, y no sabes que parte es tu proyecto y que parte el Workspace. Deberías de tomarte el tiempo para crear una carpeta con tus proyectos (fuera del workspace) y allí guardar tus programas. El Workspace no es tu proyecto.

No estoy seguro pero creo, aunque me puedo equivocar, que tu crees que el directorio wtpwebapps está dentro de tu proyecto, pero ese solamente es un espacio temporal donde Eclipse pone los archivos 'temporalmente', valga la redundancia, para que puedas hace pruebas.

Como mencioné anteriormente, cuando hagas el deploy en el servidor vas a comprender donde se guardan los archivos realmente. Revisa la documentación del servidor web que estés usando.

Por ejemplo, https://docs.jboss.org/jbossas/guide...html/dirs.html

Saludos,

Última edición por HackmanC; 16/12/2014 a las 22:37
  #9 (permalink)  
Antiguo 18/12/2014, 15:06
 
Fecha de Ingreso: diciembre-2014
Ubicación: Lima
Mensajes: 68
Antigüedad: 9 años, 4 meses
Puntos: 0
Respuesta: JSF - FileUpload

Cita:
Iniciado por HackmanC Ver Mensaje
Hola,



Allí ya las cosas se pusieron un poco confusas, si subiste la imagen en la ubicación que indicaste anteriormente, el directorio wtpwebapps. Con este código que muestras debería aparecer la imagen correctamente, sin importar si está en pruebas o es el servidor real, porque es 'relativa'. Por ese motivo fue que usaste el método getRealPath().


Primero que todo, tienes que tomar en cuenta que aunque Eclipse guarda los proyectos por defecto en el Workspace, no debería ser así; principalmente porque resulta confuso en algunos casos, y no sabes que parte es tu proyecto y que parte el Workspace. Deberías de tomarte el tiempo para crear una carpeta con tus proyectos (fuera del workspace) y allí guardar tus programas. El Workspace no es tu proyecto.
Ya movi el proyecto a una carpeta especifica, la puse en D:/, pero ahora que intente subir la imagen ya no se puede.
Cita:
Iniciado por HackmanC Ver Mensaje
No estoy seguro pero creo, aunque me puedo equivocar, que tu crees que el directorio wtpwebapps está dentro de tu proyecto, pero ese solamente es un espacio temporal donde Eclipse pone los archivos 'temporalmente', valga la redundancia, para que puedas hace pruebas.
el directorio wtpwebapps, esta fuera de mi carpeta del proyecto, esta en la raiz del workpace, despues todo lo que esta ahi, se borra.

Cita:
Iniciado por HackmanC Ver Mensaje
Como mencioné anteriormente, cuando hagas el deploy en el servidor vas a comprender donde se guardan los archivos realmente. Revisa la documentación del servidor web que estés usando.

Por ejemplo, [url]https://docs.jboss.org/jbossas/guides/installguide/r1/en/html/dirs.html[/url]

Saludos,
Revisare con mas detenimiento e investigare el tema de servidores, creí que mi servidor era la carpeta del proyecto, lo que quier hacer es crear una carpeta en C: o D y meter mis archivos ahi....mientras tanto, se soluciono solo una parte de mi problema, cuando tenga la solucion copleta, la publicare aqui...Gracias....
  #10 (permalink)  
Antiguo 21/01/2015, 21:57
 
Fecha de Ingreso: diciembre-2014
Ubicación: Lima
Mensajes: 68
Antigüedad: 9 años, 4 meses
Puntos: 0
Respuesta: JSF - FileUpload

Bueno quiero dar por solucionado el tema, investige mas a fondo lo que el usuario HackmanC me dijo y lo entendi correctamente.
Cuando yo exporto el proyecto a .war y lo levanto en el servidor que puede ser apache tomcat, glaassfish, jboss entre otros, la imagen se sube en la carpeta temporal del servidor, y desde ahi recien puedo visualizar la imagen, pero en cambio cuando estaba trabajando aun la imagen se guardaba en otro lado, desde la cual no se visualiza, el codigo mostrado arriba es correcto y funciona perfectamente.
Gracias

Etiquetas: jsf
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 09:53.