Realizar subidas de archivos con Flex
Una de las necesidades que nos pueden surgir a la hora de realizar una aplicación Flex, es la de tener que subir un archivo al servidor, para que éste lo guarde en base de datos o realice la acción que sea necesaria. En Master D nos encontramos con esta problemática cada vez que desarrollamos una nueva aplicación, por lo que he creído conveniente hablar del tema.
Para realizar correctamente una transferencia necesitamos dos cosas. Por un lado tener en la parte Flex el código necesario para comenzar una transferencia, y por otro lado en la parte del servidor, alguna página que recoja el fichero que estamos enviado. Esta página puede ser un servlet, una página php, una página asp.net, etc. En nuestro caso utilizaremos un servlet (si se usa tecnología Java, también se puede utilizar un action de struts).
Para la parte Flex, lo primero que tenemos que hacer es crear un objeto del tipo FileReference. Esta clase nos permite explorar en nuestros archivos locales para seleccionar uno, y realizar la transferencia del mismo. Cuando utilicemos esta clase, nos preocuparemos de monitorizar cuatro eventos asociados:
- SELECT: Este evento se dispara cuando al hacer browse sobre el objeto FileReference seleccionamos un archivo
- IO_ERROR: Si hemos especificado mal la url a la que queremos enviar el archivo, o ha ocurrido algún error en el servidor al procesar el fichero a subir, salta este evento.
- PROGRESS: Mientras se transfiere el fichero, se va lanzando este evento informando del progreso de la subida
- COMPLETE: Se dispara al finalizar la transferencia
Para realizar la transferencia utilizaremos un código como el siguiente (este código está disponible en el ejemplo):
//Inicializamos todos los escuchadores de evento private function init():void{ file.addEventListener(Event.SELECT, fileSelectedHandler); file.addEventListener(Event.COMPLETE, fileCompleteHandler); file.addEventListener(IOErrorEvent.IO_ERROR, fileErrorHandler); file.addEventListener(ProgressEvent.PROGRESS, fileProgressHandler); } private function fileSelectedHandler(event:Event):void{ archivoTxt.text = file.name; barraProgreso.visible = true; var url:String = "/UploadSample/uploadservlet"; var urlRequest:URLRequest = new URLRequest; urlRequest.url = url; urlRequest.method = URLRequestMethod.POST; file.upload(urlRequest, "upload", false); } private function fileCompleteHandler(event:Event):void{ barraProgreso.visible = false; Alert.show("Fichero subido correctamente"); } private function fileErrorHandler(event:IOErrorEvent):void{ Alert.show("Error de E/S al subir el archivo:\n" + event.text); } private function fileProgressHandler(event:ProgressEvent):void{ barraProgreso.setProgress(event.bytesLoaded, event.bytesTotal); } private function buscarArchivo():void{ file.browse([jpgFilter, pngFilter, gifFilter]); }
Por otro lado, en servlet del servidor utilizaremos el siguiente código (para que este código funcione hay que poner un par de librerías que os podéis descargar aquí)
import java.io.IOException; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * Servlet implementation class UploadServlet */ public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Subimos la imagen actual if (ServletFileUpload.isMultipartContent(request)) { ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory()); try { List fileItemsList = servletFileUpload.parseRequest(request); String optionalFileName = ""; FileItem fileItem = null; Iterator it = fileItemsList.iterator(); while (it.hasNext()) { FileItem fileItemTemp = (FileItem) it.next(); if (fileItemTemp.isFormField()) { if (fileItemTemp.getFieldName().equals("filename")) { optionalFileName = fileItemTemp.getString(); } } else { fileItem = fileItemTemp; } } if (fileItem != null) { // Una vez subida la imagen la guardamos en el hashmap de ImagenDAO if (fileItem.getSize() > 0) { System.out.println("Subida ok"); } else { System.out.println("Se ha subido un archivo vacio"); } }else{ System.out.println("Error en la subida del archivo"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { System.out.println("No se ha podido guardar el archivo"); } } }
Para verlo todo esto mucho más claro, está disponible este ejemplo con todo el código para cargar en el flex builder. Espero que sea de ayuda.
Saludos
January 2nd, 2009 at 5:53 am
Tengo una duda.
Existe alguna manera de enviar el archivo al servidor mediante RemoteObject??
o, por ejemplo me gustaria subir una foto pero al guardarse tome el nombre del Id de la session.
gracias, excelente articulo!!
April 7th, 2009 at 9:25 pm
hola….me gusta mucho lo ke explicas…baje el ejemplo y las librerias…y lo importo a flex builder 3 y lo corro sin hacer ningun cambio..pero no me funciona……..
me da este error
Error de E/S al subir el archivo:
Error #2038
me ayudan ???
gracias
April 7th, 2009 at 9:26 pm
porfa…si pueden ma escriben al correo….
erickajuria@yahoo.es
April 14th, 2009 at 4:31 pm
Hola erick. Ese error se da cuando la ruta a la que quieres subir el archivo es errónea. Cuando al objeto URLRequest le pasas la url, si la URL es errónea, a la hora de hacer upload, entonces da ese error.
Me he fijado que en el ejemplo, que el servlet se llama UploadServlet, pero en la URL lo llamo con uploadservlet. Esto es porque en el web.xml lo tengo mapeado de esa manera. Tal vez tú lo tengas con la U y la S en mayúsculas.
Comprueba que la ruta a la que llamas es la correcta y entonces debería de funcionar bien.
Un saludo
July 5th, 2010 at 3:59 pm
Hola, estoy iniciándome en el trabajo con Flex, y he visto el ejemplo que has publicado, el ejemplo lo haces usando un servlet, cómo sería usando una página php????