2011-03-24 24 views
29

Estoy buscando en algunos blogs, para tratar de encontrar cómo cargar 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:Carga de archivo JSF 2.0

  • creé una entidad que tiene un atributo de tipo byte [] y también se anota con una anotación de @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 "archivo" tipo y un botón de envío

  • preparé un bean gestionado para intercambiar información sobre el archivo con la página JSF.

Ahora estoy atascado, y tengo un montón de dudas:

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

  • ¿Cómo me puede ayudar un servlet?

  • ¿Necesito un servlet para hacer esto?

  • También he encontrado que en algunos el blog se menciona algo acerca de los servlets 3.0, pero no sé si mi entorno de trabajo lo está utilizando, ¿cómo si estoy usando servlets 3.0 (estoy usando JEE6)?

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

+2

JSF 2.2 está obteniendo un componente de carga de archivos que admite Ajax, llamado InputFile. Para más detalles: http://jdevelopment.nl/jsf-22/#802 – Nick

Respuesta

65

En primer lugar, este (de edad) de preguntas y respuestas asume JSF 2.0/2.1. Desde JSF 2.2 hay un componente nativo <h:inputFile> sin necesidad de bibliotecas de componentes de terceros. Ver también


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

Aquí hay un tutorial paso a paso:

  • Crear un proyecto web dinámico en blanco para Servlet 3.0 y JSF 2.0. El web.xml deben cumplir las especificaciones Servlet 3.0 y ya contienen 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> 
    

    la faces-config.xml deben cumplir especificaciones 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> 
    

  • Descargar Tomahawk 1.1.10 for 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.


  • Configurar el extensiones filtro Tomahawk en web.xml. Es el responsable de manejar las solicitudes 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 la <servlet-name> deben coincidir exactamente el <servlet-name> del FacesServlet como has definied en web.xml.


  • Crear una Facelet sencilla, 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> 
    

    Nota atributo enctype="multipart/form-data" en <h:form>, esto es muy importante con el fin de ser capaz de enviar archivos con HTTP.


  • Crear un bean gestionado sencilla, 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; 
        } 
    
    } 
    

Esa debe ser la misma. Ábralo por http://localhost:8080/projectname/upload.xhtml.

En cuanto a sus preguntas concretas:

lo que debo hacer para pasar el archivo de la JSF para el bean gestionado y luego transformarlo en un byte [] (Para poder manejarlo a EJB)?

Esto se respondió anteriormente.

¿Cómo me puede ayudar un servlet?

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

¿Necesito un servlet para hacer esto?

En un entorno JSF, el 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 for serving static content.

También he encontrado que en algunos el blog se menciona algo acerca de los servlets 3.0, pero no sé si mi entorno de trabajo está Ussing, cómo puedo si estoy Ussing servlets 3.0 (estoy Ussing JEE6)?

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

+0

Hice todo eso. Parece que no tengo más errores, pero parece que no puedo persistir ese byte [] en la base de datos. Abrí una nueva pregunta y expliqué todo lo que hice paso a paso: http://stackoverflow.com/questions/5431512/file-uploading-ussing-myfaces-tomahawk-jsf-2-0 – sfrj

+1

Intenté este método, con algunos problemas . Netbeans solo encuentra una sola etiqueta en el espacio de nombres 'http: // myfaces.apache.org/tomahawk',' inputHtml'. Con un poco de investigación, veo que este es el único archivo en el paquete 'META-INF.resources.org.apache.myfaces.custom'. PUEDO seguir usando el componente, con lo que parece ser una funcionalidad completa, pero recibo advertencias: 'JSF1064: no se puede encontrar o servir el recurso, inputFileUpload.xhtml, de la biblioteca, org.apache.myfaces.custom'. ¿Alguna idea de qué se trata esto? He visto a otros preguntar sobre lo mismo, pero siempre 0 respuestas sobre esas publicaciones. –

+0

Impresionante ... Gran ejemplo ... Me quedé sorprendido con esto durante los últimos 2 días ... –

0

La forma más sencilla es probablemente usar la etiqueta inputFileUpload que se puede encontrar en MyFaces:

http://myfaces.apache.org/

1

Publicación de blog de BalusC: Uploading files with JSF 2.0 and 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 el MultipartResolver de Spring - no necesita su MultipartMap de another blog post.

I logrado mediante la modificación de un método decode en FileRenderer como esto:

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); 

A UploadedFile es un POJO serializable simple que se usa para devolver resultados a realizar copias de frijol.

2

En JSF 2.2 puede cargar archivos fácilmente usando etiquetas sin usar commons-io o filtrar. 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> 

del diseño de su bean gestionado de la siguiente manera:

@Named 
    @RequestScoped 
    public class FileUploadBean { 

    private Part uploadedFile; 

    } 
+0

Sí, bueno, pero la pregunta es JSF 2.0 .. –

0

Debe añadir commons-fileupload-1.2.1.jar en nuestro proyecto Buil d Ruta

1.Configure 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"); 
    } 
} 

3.archivo JSF (XHTML)

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

Para completar, sólo quiero dar un completo y funcional self contained ejemplo de cómo se hace esto con JSF 2.2, ya sea con la no-Ajax y Ajax pide. Tenga en cuenta que JSF 2.2 usa diferentes espacios de nombres y need to be working with a Servlet 3.0 container (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:

+0

No me malinterpreten, pero estoy luchando con su ejemplo. No funciona para mí en absoluto. 'archivo' es siempre nulo ...? – alexander

+0

Probé en un proyecto de prueba en tomcat 7 y lo puse en funcionamiento @alexander. ¿Qué servidor estás usando? ¿Tiene algún filtro configurado? –

+0

El nuevo de JBoss - wildfly-8.1.0.Final. Y sí, ' \t \t PrimeFaces FileUpload filtros \t \t org.primefaces.webapp.filter.FileUploadFilter \t' – alexander

Cuestiones relacionadas