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.
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