1. Descripción general del curso
En el desarrollo del sistema de aplicaciones web, la función de carga de archivos es una función muy común. Hoy, hablemos principalmente de la implementación técnica relevante de la función de carga de archivos en Javaweb. Con el rápido desarrollo de la tecnología de Internet, los requisitos de experiencia de los usuarios para los sitios web están cada vez más altos. También hay muchos puntos innovadores en la tecnología de la función de carga de archivos, como la carga asíncrona, la carga de arrastrar y soltar, la carga de la carga, el monitoreo del progreso de la carga, las miniaturas de archivos, la transmisión continua del punto de interrupción de archivos grandes, la transmisión instantánea de archivos grandes, etc.
Conceptos básicos requeridos para este curso:
Comprender el contenido básico del protocolo HTTP
Tecnología básica de operación de flujo IO
Conceptos básicos de servlet
Conocimientos básicos de JavaScript/JQuery Technology
2. Conceptos básicos de carga de archivos
Para la carga de archivos, el navegador envía el archivo al lado del servidor en forma de flujo durante el proceso de carga, y todos los datos de transmisión se llevarán al lado del servidor con la solicitud HTTP. Por lo tanto, el formato del contenido solicitado al cargar el archivo debe entenderse básicamente.
Página de carga de archivo:
<Form Action = "/ItheIMaupload/uploadServlet" método = "post" enctype = "multipart/form-data"> Seleccione el archivo cargado: <input type = "file" name = "adject"/> <br/> <input type = "Subt" value = "Subt"/> </form> </form>
Contenido de solicitud HTTP:
3. Java Background utiliza servlet para recibir archivos
Es problemático si usa servlet para obtener el flujo de entrada de archivos cargados y luego analiza los parámetros de solicitud en él. Por lo tanto, en términos generales, el fondo elige usar el componente de carga de archivo de archivo común, la herramienta de código abierto de Apache.
// Código de fondo Java: Componente Commons-FileUppload Supege el archivo de la clase pública uploadServlet extiende httpservlet {public void doget (httpservletRequest solicitud, respuesta httpServletResponse) lanza ServletException, ioexception {// 1. Configurar caché diskfileitemFactory fábrica = new DiskFileItemFactory (1*1024*1024, nuevo archivo ("c:/tempfiles/")); // 2. CREAR SERVLEFILEUPLOAD Object ServletFileUpload Sfu = new ServLetFileUpload (fábrica); // Resuelve el problema chino del nombre del archivo Sfu.SetheaderEncoding ("UTF-8"); // 3. Resuelve try {list <StilItem> list = sfu.parserequest (request); // Resolver todo el contenido if (list! = Null) {for (fileItem item: list) {// Determina si es un parámetro de formulario normal if (item.isformfield ()) {// parámetros de formulario ordinario // Obtener el nombre de nombre del nombre de la cadena de fama de la cadena de fibra de forma de fasting. valor = item.getString ("UTF-8"); } else {// file if (item.getName ()! = null &&! item.getName (). Equals ("")) {// Guardar en el servidor disco duro fileutils.copyinputstreamToFile (item.getInputStream (), nuevo archivo ("c:/targetfiles/"+item.getName ()); item.delete ();} (FileUploadException e) {E.PrintStackTrace ();}} public void dopost (httpservletRequest, respuesta httpServletResponse) arroja servletException, ioexception {doget (solicitud, respuesta);}}4. Use webuploader para cargar componentes
En el extremo frontal de la página de carga de archivos, podemos elegir usar algunos componentes de carga más útiles, como el componente de código abierto de Baidu. Básicamente, este componente puede cumplir con algunas funciones diarias de la carga de archivos, como la carga asíncrona, la carga de arrastrar y soltar, pegar la carga de carga, monitoreo de progreso de carga, miniaturas de archivos e incluso puntos de interrupción de archivos grandes para continuar con la transmisión y transmisión de archivos grandes en segundos.
Descargue el componente webupload
http://fex.baidu.com/webuploader/ Descargue el paquete webupload en el sitio web oficial de Webupload
Estructura del directorio webupload:
Demostración de carga de archivo básico (incluido el progreso de carga)
Interfaz
1.1 Importar el CSS requerido, JS en la página
<Link rel = "stylesheet" type = "text/css" href = "$ {pageContext.request.contextPath} /css/webuploader.css"> <script type = "text/javaScript" src = "$ {pageContext.request.contextpath } /js/jquery-1.10.2.min.js "> </script> <script type =" text/javascript "src =" $ {pageContext.request.contextpath} /js/webuploader.js "> </script>1.2 Escriba la etiqueta de la página de carga
<
1.3 Escribir código webupload
<script type = "text/javaScript"> // 1. Inicializar webupload y configurar los parámetros globales var uploader = webuploader.create ({// flashk dirección de control swf: "$ {pageContext.request.contextpath} /js/uploader.swf", // servidor de dirección de envío: "$ {pageContext.request.conteTpathpathpathpathpathpathpathpathpathphf", // backend direcciones de dirección: "$ {pageContext.Request.conteTpathpathpathpathpathpathpathpathpathpt/uptlet /////////nalentador de direcciones,/SELECTSETLET. Etiqueta del control del archivo: "#filePicker", // archivo de carga automática automáticamente: true,}); // 2. Después de seleccionar el archivo, la visualización de la cola de información del archivo // registra el evento FileQueue: activado cuando el archivo se agrega a la cola // archivo: representa el archivo seleccionado actualmente el porteloader.on ("fileQueue", function (archivo) {// Agregar información del archivo Div $ ("#filelist"). Append ("<Div id =" "+File.id+" " class = 'fileInfo'> <span> "+file.name+" </span> <div class = 'state'> esperando cargar ... </div> <span class = 'text'> </span> </div> ");}); // 3. Registre el progreso de carga escucha // archivo: cargar archivo // Porcentaje: la proporción del progreso actual. El máximo es 1. Por ejemplo: 0.2uploader.on ("uploadProgress", function (archivo, porcentaje) {var id = $ ("#"+file.id); // Actualizar información de información ID.Find ("Div.State"). Text ("Carga ..."); // Actualizar porcentaje de carga de carga de carga de carga id.find ("span.text"). Text (Math.round (porcentaje*100)+"%");}); // 4. Regístrese y cargue la audición // archivo: archivo cargado // Respuesta: datos devueltos por fondo, return uploader.on ("uploadSuccess", function (archivo, respuesta) {// actualizar información de estado $ ("#"+file.id) .find ("div.state"). Text ("cargado");});2) Código de servlet de backend
DiskfileitemFactory fábrica = new DiskFileItemFactory (); servletFileUpload sfu = new ServletFileUpload (factory); sfu.setheaderEncoding ("UTF-8"); intente {listar <silitem> elementos = sfu.parsequest (request); para (fileitem elemento: elementos) {if (item.isformfield ()) {// información normal} else {// archivo información // juzga que solo los archivos deben guardar y procesar system.out.println ("recibido nombre del archivo:"+item.getName ()); // Copiar el archivo en el disco duro en el fondo de fondo. Archivo (ServerPath+"/"+item.getName ())); System.out.println ("Archivo guarda correctamente");}}} Catch (FileUploadException e) {E.PrintStackTRace ();}Generar miniaturas de imagen
Punto clave: llame al omloader.makethumb () Método para generar miniaturas
uploader.on ("fileQueuel", function (file) {// Informe de la información del archivo Div $ ("#fileList"). append ("<div id = '"+file.id+"' class = 'fileinfo'> <img/> <span>"+file.name+"</span> <Div class = 'state'> esperando la carga ... </div> <span class='text'></span></div>");//Make image thumbnails: Call makeThumb() method //error: Failed to create thumbnails //src: Path of thumbnails uploader.makeThumb(file,function(error,src){var id = $("#"+file.id);//If it fails, "cannot preview" is displayed if (error) {id.find ("img"). reemplazarwith ("no se puede obtener una vista previa");} // Si tiene éxito, la miniatura se mostrará a la posición especificada id.find ("img"). attr ("src", src);Arrastrar, pegar y subir
1) Agregue un DIV al área de arrastre en la página
<
2) Agregue los parámetros de arrastrar y soltar a los parámetros de configuración global del Webupploader
// 1. Inicializar webupload y configurar los parámetros globales var uploader = webuploader.create ({// flashk dirección de control swf: "$ {pageContext.request.contextpath} /js/uploader.swf", // servidor de dirección de envío: "$ {pageContext.request.conteTpathpathpathpathpathpathpathpathpathphf", // backend direcciones de dirección: "$ {pageContext.Request.conteTpathpathpathpathpathpathpathpathpathpt/uptlet /////////nalentador de direcciones,/SELECTSETLET. Elección de etiqueta del control del archivo: "#filepicker", // archivo de carga automática automáticamente: true, // habilitar la función de arrastrar y soltar, especifique el área de arrastre dnd: "#dndarea", // deshabilitar la función de arrastre y soltar en otros lugares de la página para evitar que la página abra directamente el archivo disableglobalDnd: true // enable pegar: "#iba"}});;Cargar archivos grandes en fragmentos
1) Agregue parámetros de carga de bloque a los parámetros globales del Webupploader
// 1. Inicializar webupload y configurar los parámetros globales var uploader = webuploader.create ({// flashk dirección de control swf: "$ {pageContext.request.contextpath} /js/uploader.swf", // servidor de dirección de envío: "$ {pageContext.request.conteTpathpathpathpathpathpathpathpathpathphf", // backend direcciones de dirección: "$ {pageContext.Request.conteTpathpathpathpathpathpathpathpathpathpt/uptlet /////////nalentador de direcciones,/SELECTSETLET. Etiqueta de etiqueta del control del archivo: "#filepicker", // el archivo de carga automática automáticamente: true, // habilitar la función de arrastrar y soltar, especifique el área de arrastre dnd: "#dndarea", // la función de arrastre y suelta de la página de deshabilitar en otros lugares para evitar que la página abra el archivo directamente deshabilitar: hábil: verdadero,/la función de pegar la función de pegar: "##uploader", // set en chunked en chunked. Tallado: Verdadero, // Tamaño de archivo por bloque (predeterminado 5m) Chunksize: 5*1024*1024, // Abra varios subprocesos concurrentes (predeterminado 3) subprocesos: 3, // Al cargar el archivo actual, PrepareExtFile: True});2) Monitorear tres puntos de tiempo para cargar archivos
Después de agregar las tres configuraciones anteriores, encontrará que cuando el archivo exceda de 5M, el WebUpploader enviará automáticamente el archivo al fondo.
Cada solicitud de bloque contiene información:
Puede escuchar tres puntos de tiempo importantes en las cargas de archivos en fragmentos.
ANTERIOR DE SENTACIÓN: Llame al mensaje anterior: si hay bloques, llame al archivo después del mensaje antes de que se envíe cada bloque: llamado después de que se envíen todos los bloques // 5. Monitoree los tres puntos de tiempo de carga del archivo (nota: Esta sección del código debe colocarse antes de webuploader.create) // punto de tiempo 1 :: Antes de que se carguen todos los bloques (1. La marca única del archivo se puede calcular; 2. Puede determinar si se transmite en segundos) // punto de tiempo 2: si la carga de la carga se transfiere con el fondo de la carga. Transmisión continua de punto de interrupción) // Paso 3: Después de que todos los fragmentos se carguen con éxito (1. Notifique los antecedentes de los archivos de fragmento para fusionarse) webuploader.uploader.register ({"antes del archivo-archivo": "beforesendFile", "antes de la entrega": "BEFORESEND", "After-send-file": "AfterSendFile"}, {///////////Act thall threal threal threal threal thall thort three thort three thort thort thort thort thort thort three-spte Cargue en todos los fragmentos BeforesEndfi LE: Function () {// 1. Solicite si el fondo ha guardado el bloque actual. Si existe, omita el archivo de bloque para realizar la función de transmisión continua de punto de interrupción}, // Paso 3: Llame a esta función después de que todos los bloques se cargan con éxito después de la función: function () {// 1. Si se carga en bloques, todos los archivos de bloque se fusionan a través del fondo}});Lógica de archivo antes del mensaje:
// Use el método MD5File () para calcular la etiqueta única del archivo // Esta función recibe un diferido de ForesendFile: function (file) {// Cree un diferido diferido = webuploader.deferred (); // 1. Calcule la etiqueta única del archivo, utilizada para la transmisión continua del punto de interrupción y la segunda transmisión (nueva webuploader.uploader ()). Md5File (archivo, 0,5*1024*1024) .progress (function (porcentaje) {$ ("#"+file.id) .find ("div.state"). Text ("La información del archivo es ser la información es ser la información es ser que es la información del archivo es ser el que es la información del archivo es ser el que es la información del archivo es el que es la información del archivo es el que es el archivo es el que es el archivo es el archivo. Recuperado ... ");}). Entonces (function (val) {uniquefileTag = val; $ ("#"+file.id) .find (" div.state "). Text (" información de archivo obtenida con éxito "); // solo cuando la información del archivo se obtiene con éxito, la próxima operación se realizará deferRed.Resolve ();}); // alerta (unique Filetag);//2. Solicite si el fondo ha guardado el archivo. Si existe, el archivo se omitirá para realizar la función de segundo paso // return diferido.promise ();}Lógica de mensaje antes:
// Envía una etiqueta única del archivo actual al fondo, que se utiliza para crear un directorio que guarde el archivo fortado beforesend: function () {// Lleve la etiqueta única del archivo actual a la orilla, que se utiliza para crear un directorio que guarde el archivo fragmentado this.owner.options.formdata.filemd5 = filemd5;}3) El fondo debe guardar todos los archivos fortuados
// Cree un directorio para cada archivo y guarde todos los archivos fortuados de este archivo // juzga si se ha cargado en fragmentos if (chunks! = Null) {system.out.println ("procesamiento de chunk ..."); // crea un directorio temporal para guardar todos los archivos de fragmento CHUNKSDIR = new File (ServerPath+"/"+filemd5); if (! chunksdir.exists ()) {chunksdir.mkdir ();} if (chunk! = null) {// save chunkfile chunkfile = new file (chunksdir.getPath ()+"/"+chunk); fileutils.copyputStreamtofile (item.getNputSeam (), chunkfile);};};};};};}4) La recepción notifica el backend para fusionar todos los archivos fortuados
// La recepción notifica el fondo para fusionar los archivos Logic de archivo después del archivo: AfterSendFile: Function (File) {// 1. Si se carga en fragmentos, fusione todos los archivos de fragmentos a través del fondo // solicitar el fondo para fusionar archivos $ .AJAX ({type: "post", url: "$ {pageContext.request.contextPath}/uploadCheckservlet? Action = MergeChunks", data: {// FileMd5: filemd5: filemd5, // File NameServlet FileName: File.name}, DataType: "JSON", Success: Function (Response) {Alert (Response.msg);}});} // Background Merge TODOS LOS ARCHIVOS DE TRABAJO if ("MergeChunks" .Equals (Action)) {System.out.println ("Iniciar archivos de fusión ..."); // merge de archivo filemd5 = request.getParameter (""); ""); ""); "" ");" "". FileName = request.getParameter ("FileName"); // Leer todos los archivos en el archivo del directorio f = nuevo archivo (serverPath+"/"+filemd5); archivo [] filearray = f.listFiles (new fileFilter () {// Excluir directorio, siempre que el archivo público sea el archivo boolean (el archivo PathName) {if (if (ife.isDirectory () verdadero;}}); // Convertir a una colección para facilitar la lista de clasificación <Sche> fileList = new ArrayList <ScheS> (arrays.aslist (fileArray)); // Ordena de Small To Large CollectS.sort (fileList, New Comparator <Archil> () {Public int Compare (File O1, File O2) {if (integer.Parseint (o1.get) Integer.parseInt(o2.getName())){return -1;}return 1;}});File outputFile = new File(serverPath+"/"+fileName);//Create the file outputFile.createNewFile();//Output stream FileChannel outChannel = new FileOutputStream(outputFile).getChannel();//Merge FileChannel inChannel; para (archivo de archivo: filelist) {Inchannel = new FileInputStream (archivo) .getChannel (); Inchannel.Transferto (0, Inchannel.size (), outchannel); Inchannel.close (); // Eliminar archivo.delete ();} // borrar el archivo de la carpeta Tempfile = nuevo archivo (serverpath+"/" "" Filemd5); if (tempfile.isDirectory () && tempfile.exists ()) {tempfile.delete ();} // cierre el stream outchannel.close (); respuesta.setContentType ("text/html; charset = utf-8"); respuesta.getwriter (). exitosamente/"}");}Continuar los puntos de interrupción de archivos grandes
Según la implementación de la carga de bloque, es muy simple implementar la transmisión continua del punto de interrupción. ! !
Interfaz:
// Punto de tiempo 2: Si hay carga de bloque, esta función se llama antes de cada carga de carga // bloque: representa el objeto de bloque actual befeforesend: function (block) {// 1. Solicite si el fondo ha guardado el bloque actual. Si existe, omita el archivo de bloque para realizar la función de transmisión continua de punto de interrupción var diferido = webuploader.deferred (); // Solicite si el fondo guarda la información del archivo. Si se ha guardado, se omitirá. If it has not, the chunk content will be sent $.ajax({type:"POST",url:"${pageContext.request.contextPath}/UploadCheckServlet?action=checkChunk",data:{//The file unique mark fileMd5:fileMd5,//The current chunk subscript chunk:block.chunk,//The current chunk size chunkSize:b LOCK.END BLOCK.START}, DataType: "json", éxito: function (respuesta) {if (respuesta.iDiAGET) {// El bloque existe, omita el bloque de block deferred.reject ();} else {// el bloque no existe o no existe incompleto, y reenvíe el contenido del contenido del bloque de bloqueo y deje que el archivo de la corriente y la etiqueta de la etiqueta y el archivo de la etiqueta del bloque de la corriente y la etiqueta de la etiqueta. Antecedentes Crear el directorio que guarde el archivo bloquea this.owner.options.formdata.filemd5 = filemd5; return deferred.promise (); },Entre bastidores:
// Verifique si el fragmento existe o guarda la solicitud privada de checkchunk void (httpservletRequest, httpservletResponse respuesta) lanza ioException, filenotfoundException {system.println ("checkChunk ..."); string filemd5 = request.getParameter ("filemd5"); string chunk = request.getParameter ("CHUNKSHIMD5 = SELIT.GETPARAMETER (" FILEMD5 "); String chunk = request.getParamETTER (" String filemd5 = Solic. request.getParameter ("chunksize"); archivo checkFile = new File (serverPath+"/"+filemd5+"/"+chunk); respuesta.setContentType ("text/html; charset = utf-8"); // verifique si el archivo existe y el tamaño es consistente si (checkfile.exists () &&&&&&&&&&&&&&&&&&&&&&&&&&& && checkFile.length () == Integer.ParseInt (chunksize)) {Response.getWriter (). Write ("{{/" IfExist/": 1}");} else {Response.getWriter (). Write ("{/" IfExist/": 0}");}}}Transferencia de archivos en segundos
Antes de todas las solicitudes de bloque, la segunda función de transferencia se puede implementar. ! !
Interfaz:
befeforesendFile: function (file) {// crea un DefferedVar diferido = webuploader.deferred (); // 1. Calcule la marca única del archivo, utilizada para la transmisión continua del punto de interrupción y la segunda transmisión (nueva webuploader.uploader ()). Md5file (archivo, 0,5*1024*1024) .progress (function (porcentaje) {$ ("#"+file.id) .find ("div.state"). Text ("obtenga el archivo información ...");}). = val; $ ("#"+File.id) .Find ("Div.State"). Text ("Información de archivo obtenida con éxito"); // 2. $ .AJAX ({Tipo: "Post", URL: "$ {PageContext.Request.ContextPath}/uploadCheckServlet? Action = FileCheck", Data: {// La etiqueta única del archivo filemd5: filemd5}, dataType: "json", éxito: function (respuesta) {if (respuesta.ifexist) {$ ("#"+file.id) .find ("div.state"). text ("transferido con éxito"); Deferred.resolve ();}}});}); // return Deferredreturn Deferred.promise ();},Entre bastidores:
// Verifique si los datos MD5 del archivo están relacionados con la base de datos Void FileCheck (httpservletRequest, httpServletResponse Respuesta) lanza ioexception, filenotfoundException {string filemd5 = request.getParameter ("filemd5"); // simula el mapa de la base de la base de la base de database Hashmap <string, string> (); database.put ("576018603f4091782b68b78af85704a1", "01. Curso Revisar.itcast "); respuesta.setContentType (" text/html; charset = utf-8 "); if (database.containskey (filemd5)) {Response.getWrither (). Write (" {/"ifexist/": 1} ");} else {Response.getWriter (). WriteLo anterior es una explicación de ejemplo de la carga y descarga de archivos Javaweb que el editor le presentó (tecnología de carga de archivos genial). Espero que sea útil para todos. Si tiene alguna pregunta, déjame un mensaje y el editor responderá a todos a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!