subir fileupload example archivos jsf file-upload jsf-2
Tomahawk 1.1.10 para JSF 2.0

fileupload - jsf subir archivos



Carga de archivo JSF 2.0 (8)

Estoy buscando en algunos blogs, para tratar de encontrar cómo subir archivos usando JSF 2.0. Pero todas las soluciones me confunden. Me gustaría saber qué es exactamente lo que necesito para poder subir un archivo (MP3, PDF, video ... cualquier tipo) y almacenarlo en una base de datos como @Lob. Esto es lo que he hecho hasta ahora:

  • Creé una entidad que tiene un atributo de tipo byte [] y también está anotado con una anotación @Lob.

  • Creé un EJB que introducirá la entidad con un método que tiene un byte [] como parámetro y lo inserta en la base de datos utilizando la clase EntityManager (método de persistencia).

  • Creé una página JSF con una etiqueta de entrada de tipo "archivo" y un botón de enviar

  • Preparé un frijol administrado para intercambiar información sobre el archivo con la página JSF.

Ahora estoy atascado, y tengo muchas dudas:

  • ¿Qué debo hacer para pasar el archivo de JSF al bean administrado y luego transformarlo en un byte [] (Para poder manejarlo en el EJB)?

  • ¿Cómo puede ayudarme un servlet?

  • ¿Necesito un servlet para hacer esto?

  • También encontré que en algún blog menciona algo acerca de servlets 3.0, pero no sé si mi entorno de trabajo lo está usando, ¿cómo puedo hacerlo si estoy usando servlets 3.0 (estoy usando JEE6)?

Nunca cargué archivos antes y tampoco estoy muy familiarizado con los servlets. Estoy confundido, alguien podría darme algunos consejos de inicio, por favor?


Debe agregar commons-fileupload-1.2.1.jar en nuestro proyecto Build Path

1.Configurar el archivo web.xml:

Web.xml <filter> <filter-name>PrimeFaces FileUpload Filter</filter-name> <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class> </filter> <filter-mapping> <filter-name>PrimeFaces FileUpload Filter</filter-name> <servlet-name>Faces Servlet</servlet-name> </filter-mapping> <mime-mapping> <extension>png</extension> <mime-type>image/png</mime-type> </mime-mapping>

2. Crear ManagedBean

@ManagedBean @SessionScoped public class FileUploadBean implements Serializable{ public FileUpload (){ } private StreamedContent file; public void loadFile(FileUploadEvent event) throws IOException, InterruptedException { InputStream input = new ByteArrayInputStream(event.getFile().getContents()); file= new DefaultStreamedContent(input, "image/jpg"); } }

Archivo 3.jsf (xhtml)

<h:form enctype="multipart/form-data"> <p:fileUpload fileUploadListener="#{fileUploadBean.file}" sizeLimit="100000" allowTypes="/(/.|//)(gif|jpe?g|png|bmp)$/"/> </h:form>


En JSF 2.2 puede cargar fácilmente archivos usando tag sin usar commons-io o filter. Esta etiqueta admite tanto el proceso normal como el ajax.

Normal:

<h:inputFile id="file" value="#{fileUploadBean.uploadedFile}"/> <h:commandButton id="button" action="#{fileUploadBean.sumbit()}" value="Upload"/>

Ajax:

<h:inputFile id="file" value="#{fileUploadBean.uploadedFile}"/> <h:commandButton id="button" value="submit"> <f:ajax execute="@all" render="@all" onevent="statusUpdate"/> </h:commandButton>

Diseña tu bean administrado de la siguiente manera:

@Named @RequestScoped public class FileUploadBean { private Part uploadedFile; }



La forma más fácil es, probablemente, utilizar la etiqueta inputFileUpload que puedes encontrar en MyFaces:

http://myfaces.apache.org/


Para completar, solo deseo proporcionar un ejemplo autónomo completamente funcional de cómo se hace esto con JSF 2.2, ya sea con solicitudes que no sean Ajax o Ajax . Tenga en cuenta que JSF 2.2 usa diferentes espacios de nombres y necesita trabajar con un contenedor Servlet 3.0 (como Tomcat 7.0.x, JBoss AS 6.x y 7.x y GlassFish 3.x).

fileUpload.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head /> <h:body> <h:form enctype="multipart/form-data"> <h:inputFile value="#{uploadBean.file}" /> <h:commandButton value="Post Upload" action="#{uploadBean.upload}" /> </h:form> <h:form enctype="multipart/form-data"> <h:inputFile value="#{uploadBean.file}" /> <h:commandButton value="Ajax Upload"> <f:ajax listener="#{uploadBean.upload}" execute="@form" render="countOutput" /> </h:commandButton> <!-- Counts the uploaded items --> <h:outputText id="countOutput" value="Files uploaded #{uploadBean.filesUploaded}" /> </h:form> </h:body> </html>

UploadBean.java:

@ManagedBean @ViewScoped public class UploadBean { private int filesUploaded = 0; //javax.servlet.http.Part (Servlet 3.0 API) private Part file; private String fileContent; /** * Just prints out file content */ public void upload() { try { fileContent = new Scanner(file.getInputStream()) .useDelimiter("//A").next(); System.out.println(fileContent + " uploaded"); filesUploaded++; } catch (IOException e) { e.printStackTrace(); } } public int getFilesUploaded() { return filesUploaded; } public Part getFile() { return file; } public void setFile(Part file) { this.file = file; } }

Ver también:


Publicación de blog de BalusC: la carga de archivos con JSF 2.0 y Servlet 3.0 es lo que me salvó, porque tuve problemas al ejecutar RichFaces 4 fileUpload tag con Spring WebFlow.

Vale la pena modificar el código de BalusC para usar Springpart MultipartResolver ; no necesita su MultipartMap de otra publicación de blog .

Lo logré modificando un método de decode en FileRenderer así:

UploadedFile ret = null; Object req = context.getExternalContext().getRequest(); if (req instanceof MultipartHttpServletRequest) { MultipartFile file = ((MultipartHttpServletRequest)req).getFile(clientId); File temp = null; try { temp = File.createTempFile("_UPLOAD_", null); file.transferTo(temp); String name = new File(file.getOriginalFilename()).getName(); ret = new UploadedFile(temp, name); } catch (IOException e) { throw new RuntimeException("Could not create temp file.", e); } } else { throw new IllegalStateException("Request is not multipart. Use spring''s multipart resolver."); } // If no file is specified, set empty String to trigger validators. ((UIInput) component).setSubmittedValue( ret == null ? EMPTY_STRING : ret);

Un UploadedFile es un POJO serializable simple usado para devolver resultados al bean de respaldo.



En primer lugar, esta (antigua) pregunta y respuesta asume JSF 2.0 / 2.1. Desde JSF 2.2 hay un componente nativo <h:inputFile> sin necesidad de bibliotecas de componentes de terceros. Consulte también Cómo subir archivos usando JSF 2.2 <h: inputFile>? ¿Dónde está el archivo guardado?

La forma más fácil sería usar Tomahawk para JSF 2.0 . Ofrece un componente <t:inputFileUpload> .

Aquí hay un tutorial paso a paso:

  • Cree un proyecto web dinámico en blanco para Servlet 3.0 y JSF 2.0. El web.xml debe cumplir con la especificación Servlet 3.0 y ya contiene el servlet JSF:

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="YourProjectName" version="3.0"> <display-name>Your Project Name</display-name> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> </web-app>

    El faces-config.xml debe cumplir con la especificación JSF 2.0:

    <?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0"> </faces-config>

  • Descargue Tomahawk 1.1.10 para JSF 2.0 . Extraiga el archivo zip, vaya a la carpeta /lib y copie todos los archivos *.jar en su /WEB-INF/lib .

    Son 18 archivos, de los cuales batik*.jar y xml*.jar son innecesarios para usar solo el componente t:inputFileUpload . Podrías dejarlos fuera.

  • Configure el filtro de extensiones Tomahawk en web.xml . Es el responsable de gestionar multipart/form-data solicitudes de multipart/form-data que se requieren para poder enviar archivos a través de HTTP.

    <filter> <filter-name>MyFacesExtensionsFilter</filter-name> <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFacesExtensionsFilter</filter-name> <servlet-name>Faces Servlet</servlet-name> </filter-mapping>

    Tenga en cuenta que el <servlet-name> debe coincidir exactamente con el <servlet-name> de FacesServlet como FacesServlet en web.xml .

  • Crea un Facelet simple, upload.xhtml :

    <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:t="http://myfaces.apache.org/tomahawk" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:head> <title>Tomahawk file upload demo</title> </h:head> <h:body> <h:form enctype="multipart/form-data"> <t:inputFileUpload value="#{bean.uploadedFile}" /> <h:commandButton value="submit" action="#{bean.submit}" /> <h:messages /> </h:form> </h:body> </html>

    Tenga en cuenta el enctype="multipart/form-data" en <h:form> , esto es muy importante para poder enviar archivos con HTTP.

  • Crea un bean administrado simple, com.example.Bean :

    package com.example; import java.io.IOException; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.context.FacesContext; import org.apache.commons.io.FilenameUtils; import org.apache.myfaces.custom.fileupload.UploadedFile; @ManagedBean @RequestScoped public class Bean { private UploadedFile uploadedFile; public void submit() throws IOException { String fileName = FilenameUtils.getName(uploadedFile.getName()); String contentType = uploadedFile.getContentType(); byte[] bytes = uploadedFile.getBytes(); // Now you can save bytes in DB (and also content type?) FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(String.format("File ''%s'' of type ''%s'' successfully uploaded!", fileName, contentType))); } public UploadedFile getUploadedFile() { return uploadedFile; } public void setUploadedFile(UploadedFile uploadedFile) { this.uploadedFile = uploadedFile; } }

Eso debería ser. http://localhost:8080/projectname/upload.xhtml por http://localhost:8080/projectname/upload.xhtml .

En cuanto a sus preguntas concretas:

¿Qué debo hacer para pasar el archivo de JSF al bean administrado y luego transformarlo en un byte [] (Para poder manejarlo en el EJB)?

Esto se responde arriba.

¿Cómo puede ayudarme un servlet?

Puede procesar y controlar solicitudes / respuestas HTTP. En un entorno JSF, FacesServlet ya hace todo el trabajo.

¿Necesito un servlet para hacer esto?

En un entorno JSF, FacesServlet es obligatorio. Pero ya lo proporciona la API, no necesita escribir uno usted mismo. Sin embargo, para poder descargar archivos desde una base de datos, otro servlet es definitivamente útil. Puede encontrar un ejemplo básico aquí: Servlet para servir contenido estático .

También encontré que en algún blog menciona algo sobre servlets 3.0, pero no sé si mi entorno de trabajo lo está usando, ¿cómo puedo hacerlo si uso servlets 3.0 (estoy usando JEE6)?

Si está utilizando un contenedor Servlet 3.0 como Glassfish 3, JBoss AS 6, Tomcat 7, etc. y el web.xml está declarado como Servlet 3.0, entonces definitivamente está utilizando Servlet 3.0. Servlet 3.0 es parte de Java EE 6.