En el desarrollo del sistema de aplicaciones web, las funciones de carga y descarga de archivos son funciones comúnmente utilizadas. Hoy, hablemos sobre la implementación de las funciones de carga y descarga de archivos en Javaweb.
Para la carga de archivos, el navegador envía el archivo al servidor en forma de transmisión durante el proceso de carga. Es más problemático si usa directamente Servlet para obtener el flujo de entrada del archivo cargado y luego analice los parámetros de solicitud en él. Por lo tanto, generalmente se elige usar el componente de archivo común, el componente de carga de archivos de la herramienta de código abierto Apache. El paquete JAR del componente de carga de archivo común se puede descargar en el sitio web oficial de Apache, o se puede encontrar en la carpeta LIB de puntales. La función de la carga de Struts se basa en esta implementación. Common-FileUpload depende del paquete Common-IO, por lo que también debe descargar este paquete.
1. Construcción del entorno de desarrollo
Cree un proyecto FileUploadandDownload y agregue el paquete JAR de componente de carga de archivo CommonsPload de Apache, como se muestra en la figura a continuación:
2. Implementar la carga de archivos
2.1. Página de carga de archivo y página de mensaje de mensaje
El código de la página upload.jsp es el siguiente:
<%@ page lenguaje = "java" pageEncoding = "utf-8"%> <! DocType html> <html> <fead> <title> Archivo de carga </title> </head> <body> <form action = "$ {pageContext.Request.contextPath}/servlet/uploadhandleseB user: <input type = "text" name = "username"> <br/> upload file 1: <input type = "file" name = "file1"> <br/> de carga de carga 2: <input type = "file" name = "file2"> <br/> <input type = "enviar" value = "enviar"> </borm> </body> </html> El código para el código.jsp es el mensaje de seguimiento. imprimir? <%@ page lenguaje = "java" pageEncoding = "UTF-8"%> <! DocType Html> <html> <fead> <title> mensaje de mensaje </title> </head> <body> $ {mensaje} </body> </html>>2.2. Procesamiento de servlets para cargas de archivos
El código de la carga de carga es el siguiente:
paquete me.gacl.web.controller; import java.io.file; import java.io.fileOutputStream; import java.io.ioException; import java.io.inputstream; import java.util.list; import javax.servlet.servletException; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; importar org.apache.commons.fileUpload.fileitem; importar org.apache.commons.fileupload.disk.diskfileitemFactory; importar org.apache.commons.fileUpload.servlet.servletFileUpload; Public Class uploadHandleServlet extiende httpservlet {public void doget (httpservletRequest request, httpServletResponse respuesta) lanza ServletException, ioexception {// Obtener el directorio guardado del archivo cargado, almacenar el archivo cargado en el directorio web-Inf, y no permitir el acceso directo desde el mundo exterior para garantizar la seguridad del archivo upcado. this.getServletContext (). GetRealPath ("/Web-Inf/upload"); Archivo archivo = nuevo archivo (savePath); // juzga si el directorio guardado del archivo cargado existe si (! File.exists () &&! File.isDirectory ()) {System.out.println (SavePath+"El directorio no existe, debe crearse"); // Crear el directorio file.mkdir (); } // El mensaje solicita a String Message = ""; Pruebe {// use el componente de carga del archivo Apache para manejar los pasos de carga de archivo: // 1. Cree una fábrica de fábrica de Factory de DISKFILETMATIVORY // 2. Crear un archivo de carga analizador ServletFileUpload upload = new ServletFileUpload (fábrica); // Resolver la carga china Garlume. // 3. Determine si los datos enviados son los datos del formulario de carga si (! ServletFileUpload.IsmultipartContent (request)) {// Obtenga retorno de datos de la manera tradicional; } // 4. Use el analizador ServletFileUpload para analizar los datos cargados. El resultado de análisis devuelve una recopilación de la lista <FileItem>. Cada FileItem corresponde al elemento de entrada de una lista de formulario de formulario <LeitEitem> list = upload.parserequest (solicitud); for (fileItem item: list) {// Si los datos de un elemento de entrada normal están encapsulados en el fileitem if (item.isformfield ()) {String name = item.getFieldName (); // Resolver el problema chino de datos de los elementos de entrada ordinarios Valor de cadena = item.getString ("UTF-8"); // value = new String (value.getBytes ("ISO8859-1"), "UTF-8"); System.out.println (nombre + "=" + valor); } else {// Si el elemento del archivo encapsula el archivo cargado // obtener el nombre de archivo cargado, string filename = item.getName (); System.out.println (nombre de archivo); if (filename == null || filename.trim (). Equals ("")) {continuar; } // Nota: Los nombres de archivo enviados por diferentes navegadores son diferentes. Algunos navegadores envían archivos con rutas, tales como: c: /a/b/1.txt, y algunos son solo nombres de archivos simples, como: 1.txt // procesar la parte de ruta del nombre de archivo del archivo cargado obtenido, solo la parte del nombre de archivo está retenido filename = filename.substring (filename.lastIndexof ("//")+1); // Obtenga la secuencia de entrada del archivo cargado en el elemento inputStream in = item.getInputStream (); // Crear una salida de archivo FileOutputStream Out = New FileOutputStream (SavePath + "//" + FileName); // Crear un búfer de byte búfer [] = nuevo byte [1024]; // La identificación de si se han leído los datos en el flujo de entrada es int len = 0; // La secuencia de entrada se lee en el bucle de búfer, (len = in.read (buffer))> 0 significa que todavía hay datos en while ((len = in.read (buffer))> 0) {// use fileoutputstream outture stream para escribir los datos de búfer en el directorio especificado (guardarpath + "//" + nombre de archivo) out.write (buffer, 0, len); } // Cierre la transmisión de la transmisión en.close (); // cierre la salida stream out.close (); // Eliminar el archivo temporal generado al procesar el archivo de carga item.delete (); Message = "La carga de archivo se cargó correctamente!"; }}}} catch (Exception e) {Message = "Falling Falling!"; E.PrintStackTrace (); } request.setAttribute ("Mensaje", mensaje); request.getRequestDIsPatcher ("/Message.jsp"). Foring (solicitud, respuesta); } public void dopost (httpservletRequest solicitud, respuesta httpservletreSponse) lanza ServletException, ioexception {doget (solicitud, respuesta); }}Registre la carga de la carga en el archivo Web.xml
<Servlet> <Servlet-name> uploadHandleServlet </servlet-name> <ervlet-class> me.gacl.web.controller.uploadhandleservlet </servlet-class> </servlet> <ervlet-mapping> </Servlet-mapping>
El efecto de operación es el siguiente:
Una vez que el archivo se carga correctamente, el archivo cargado se guarda en el directorio de carga en el directorio web-INF, como se muestra en la figura a continuación:
2.3. Detalles de la carga de archivos
Aunque el código anterior puede cargar con éxito archivos en el directorio especificado en el servidor, hay muchos detalles pequeños a los que se debe prestar atención en la función de carga de archivos. Los siguientes puntos deben recibir especial atención.
1. Para garantizar la seguridad del servidor, los archivos de carga deben colocarse en un directorio al que el mundo exterior no pueda acceder directamente, como en el directorio web-INF.
2. Para evitar la sobrescritura del archivo, se debe generar un nombre de archivo único para cargar el archivo.
3. Para evitar que aparezcan demasiados archivos en un directorio, debe usar el algoritmo hash para romper el almacenamiento.
4. El valor máximo de los archivos cargados debe ser limitado.
5. Para limitar el tipo de archivos cargados, al recibir el nombre de archivo cargado, determine si el nombre del sufijo es legal.
En respuesta a los 5 temas detallados anteriores, mejoremos el UploadHandleServlet. El código mejorado es el siguiente:
paquete me.gacl.web.controller; import java.io.file; import java.io.fileOutputStream; import java.io.ioException; import java.io.inputstream; import java.util.list; import java.util.uuid; import javax.servlet.servletException; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; importar org.apache.commons.fileUpload.fileitem; importar org.apache.commons.fileUpload.fileUploadbase; importar org.apache.commons.fileUpload.ProgressListener; importar org.apache.commons.fileupload.disk.diskfileitemFactory; importar org.apache.commons.fileUpload.servlet.servletFileUpload; / ** * @classname: uploadHandleservlet * @Description: TODO (uso una oración para describir la función de esta clase) * @Author: Garante CANGLANG * @DATE: 2015-1-3 11:35:50 pm * */ public class uploadLeServlet extiende httpServlet {public vide (httpServletRest Solicitud, httOWSOWServlet) extiende httPsEnservlet {public okget (httpServletRest, request, htthandleServlet). ServletException, IOException {// Obtenga el directorio guardado del archivo cargado, almacene el archivo cargado en el directorio web-INF y no permite el acceso directo desde el mundo exterior para garantizar la seguridad de los archivos cargados String savePath = this.getServletContext (). // El archivo temporal generado durante la carga se guarda mediante la cadena del directorio temppath = this.getServletContext (). GetRealPath ("/Web-Inf/Temp"); Archivo tmpfile = nuevo archivo (TEMPPATH); if (! tmpfile.exists ()) {// Crear un directorio temporal tmpfile.mkdir (); } // El mensaje solicita a String Message = ""; Pruebe {// use el componente de carga del archivo Apache para manejar los pasos de carga de archivo: // 1. Cree una fábrica de fábrica de Factory de DISKFILETMATIVORY // Establecer el tamaño del búfer de la fábrica. Cuando el tamaño de archivo cargado excede el tamaño del búfer, se generará y almacenará un archivo temporal en el directorio temporal especificado. Factory.setsizethreshold (1024*100); // Establezca el tamaño del búfer en 100kb. Si no se especifica, el tamaño del búfer es de 10 kB de forma predeterminada. // Establecer el directorio de almacenamiento del archivo temporal generado durante la carga fábrica.setRepository (tmpfile); // 2. Crear un archivo de carga analizador ServletFileUpload upload = new ServletFileUpload (fábrica); // Listen to file upload progress upload.setProgressListener(new ProgressListener(){ public void update(long pBytesRead, long pContentLength, int arg2) { System.out.println("File size is: " + pContentLength + ", currently processed: " + pBytesRead); /** * File size is: 14608, currently processed: 4096 File size is: 14608, Actualmente procesado: el tamaño del archivo 7367 es: 14608, actualmente procesado: el tamaño del archivo 11419 es: 14608, actualmente procesado: 14608 */}}); // Resolver la carga china Garlume. // 3. Determine si los datos enviados son los datos del formulario de carga si (! ServletFileUpload.IsmultipartContent (request)) {// Obtenga retorno de datos de la manera tradicional; } // Establezca el valor máximo del tamaño del archivo único cargado, que actualmente se establece en 1024*1024 bytes, es decir, 1MB upload.setFilesizeMax (1024*1024); // Establecer el valor máximo del número total de archivos cargados, el valor máximo = la suma de los tamaños máximos de múltiples archivos cargados al mismo tiempo, que actualmente se establece en 10MB upload.setsizEmax (1024*1024*10); // 4. Use el analizador ServletFileUpload para analizar los datos cargados. El resultado de análisis devuelve una recopilación de la lista <FileItem>, cada FileItem corresponde al elemento de entrada de un formulario Lista de formulario <LeItem> list = upload.parserequest (solicitud); for (fileItem item: list) {// Si el fileitem encapsula los datos de los elementos de entrada ordinarios if (item.isformfield ()) {string name = item.getFieldName (); // resuelve el problema chino de datos de los elementos de entrada ordinarios Valor de cadena = item.getString ("UTF-8"); // value = new String (value.getBytes ("ISO8859-1"), "UTF-8"); System.out.println (nombre + "=" + valor); } else {// Si el fileitem encapsula el archivo cargado // obtener el nombre del archivo cargado, string filename = item.getName (); System.out.println (nombre de archivo); if (filename == null || filename.trim (). Equals ("")) {continuar; } // Nota: Los nombres de archivo enviados por diferentes navegadores son diferentes. Algunos navegadores envían nombres de archivo con rutas, como: c: /a/b/1.txt, mientras que algunos son solo nombres de archivo simples, como: 1.txt // Process la parte de ruta del nombre de archivo del archivo cargado obtenido, solo la parte del nombre de archivo está retenido FileName = filename.substring (FileName.lastIndexof ("//")+1); // Obtenga la extensión de la cadena de archivo cargado FileExtName = FileName.Substring (FileName.lastIndexOf (".")+1); // Si necesita limitar el tipo de archivo cargado, puede usar la extensión del archivo para determinar si el tipo de archivo cargado es legal System.out.println ("La extensión del archivo cargado es:"+FileExtName); // Obtenga la secuencia de entrada del archivo cargado en el elemento inputStream in = item.getInputStream (); // Obtenga el nombre de la cadena guardada de archivo SaveFileName = MakefileName (FileName); // Obtener la cadena de directorio de guardar archivo realSavePath = MakEpath (SaveFileName, SavePath); // Crear un archivo de salida de archivo FileOutputStream Out = new FileOutputStream (RealSavePath + "//" + SaveFileName); // Crear un búfer de byte búfer [] = nuevo byte [1024]; // La identificación de determinar si los datos en el flujo de entrada se han leído es int len = 0; // La secuencia de entrada se lee en el búfer, (len = in.read (buffer))> 0 significa que todavía hay datos en while ((len = in.read (buffer))> 0) {// use FileOutputStream Output Stream para escribir los datos del búfer en el directorio especificado (SavePath + "//" + FileName) out.write (buffer, 0, Len); } // Cierre la transmisión de la transmisión en.close (); // cierre la salida stream out.close (); // eliminar el archivo temporal generado al procesar la carga del archivo //item.delete (); Message = "La carga de archivo se cargó correctamente!"; }}} Catch (FileUploadBase.FillesizeLImiteXECEDEDException e) {E.PrintStackTrace (); request.setAttribute ("Mensaje", "se excede el valor máximo de un solo archivo !!!"); request.getRequestDIsPatcher ("/Message.jsp"). Foring (solicitud, respuesta); devolver; } Catch (FileUploadBase.SizElimiteExExEdException e) {E.PrintStackTrace (); request.setAttribute ("Mensaje", "El tamaño total del archivo cargado excede el valor máximo del límite!"); request.getRequestDIsPatcher ("/Message.jsp"). Foring (solicitud, respuesta); devolver; } catch (Exception e) {Message = "Falling Falling!"; E.PrintStackTrace (); } request.setAttribute ("Mensaje", mensaje); request.getRequestDIsPatcher ("/Message.jsp"). Foring (solicitud, respuesta); } /*** @method: makefileName* @Description: Genere el nombre del archivo del archivo cargado, con el nombre del archivo como: uuid+ "_"+ el nombre original del archivo* @anthor: 发官网* @param fileName el nombre original del archivo* @return uUid+ "_"+ el nombre original del archivo* /string privado MakeFilEname (string fileName (string fileName (string fileName) // Para evitar la sobrescritura del archivo, se debe generar un nombre de archivo único para cargar el archivo. Return uuid.randomuuid (). ToString () + "_" + nombre de archivo; } / *** Para evitar que aparezcan demasiados archivos en un directorio, debe usar el algoritmo hash para romper el almacenamiento* @method: makepath* @Description:* @anthor: el lono y arrogante wolf** @param filen nombre de archivo, generar el directorio de almacenamiento basado en el nombre de archivo* @param guardar el archivo de almacenamiento* @ @@return nearnear* string string string (string string string string (string string string string (string string string string (string string string string directorath (string string string string string striebat FileName, String SavePath) {// Obtenga el valor hashcode del nombre del archivo, y lo que obtiene es la dirección del nombre de archivo de objeto de cadena en la memoria int hashcode = filename.hashcode (); int dir1 = hashcode & 0xf; // 0--15 int dir2 = (hashcode & 0xf0) >> 4; // 0-15 // Construye una nueva cadena de directorio de guardado dir = SavePath + "//" + Dir1 + "//" + Dir2; // cargar/2/3 de carga/3/5 // El archivo puede representar tanto el archivo como el archivo del archivo de directorio = nuevo archivo (dir); // Si el directorio no existe si (! File.exists ()) {// crea el directorio file.mkdirs (); } return dir; } public void dopost (httpservletRequest solicitud, respuesta httpservletreSponse) lanza ServletException, ioexception {doget (solicitud, respuesta); }}Después de mejorar los cinco pequeños detalles mencionados anteriormente, nuestra función de carga de archivos ha sido relativamente completa.
3. Descarga de archivos
3.1. Enumere los recursos de archivo proporcionados para descargar
Queremos proporcionar los recursos de archivo en el sistema de aplicaciones web a los usuarios para descargar. Primero, necesitamos tener una página para enumerar todos los archivos en el directorio de archivos cargado. Cuando el usuario haga clic en el archivo de descarga de Hyperlink, se descargará y escribirá un ListFileservlet para enumerar todos los archivos descargados en el sistema de aplicaciones web.
El código de ListFileServlet es el siguiente:
paquete me.gacl.web.controller; import java.io.file; import java.io.ioException; import java.util.hashmap; import java.util.map; import javax.servlet.servletException; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; / ** * @classname: listFileservlet * @Description: Lista todos los archivos descargados en el sistema web * @author: Garante * @Date: 2015-1-4 9:54:40 pm * */ public class ListFileservlet extiende httpservlet {public void (htttpServeSquest solicitud, htttpservlet-respuesta). // Obtenga el directorio para cargar archivos String String uploadFilePath = this.getServletContext (). GetRealPath ("/web-Inf/upload"); // almacenar el nombre del archivo que se descargará map <string, string> filenamEmap = new Hashmap <String, String> (); // Recursivamente atraviesa todos los archivos y directorios en el directorio de FilePath, y almacene el nombre del archivo del archivo en el archivo ListFile de colección de mapas (nuevo archivo (uploadFilePath), filenamEmap); // el archivo puede representar un archivo o un directorio // enviar la colección de mapas a la página listFile.jsp para la solicitud. request.getRequestDIsPatcher ("/listFile.jsp"). Foring (solicitud, respuesta); } /*** @method: listfile* @Description: recursivamente atraviesa todos los archivos en el directorio especificado* @anthor: 光克* @param archivo significa un archivo, y también representa un directorio de archivos* @param Map Colloll if (! file.isfile ()) {// enumere todos los archivos y directorios en los archivos de archivos de directorio [] = file.listfiles (); // transferir archivos [] matriz para (archivo f: archivos) {// recursivo listfile (f, map); }} else { /*** procesa el nombre del archivo. El archivo cargado se renombra en forma de nombre UUID_FILE. Elimine la parte UUID_ del archivo de nombre del archivo.getName (). IndexOf ("_") para recuperar la ubicación del carácter "_" en la cadena. Si el nombre del archivo es similar a: 9349249849-88343-8344_a_fan_davi.avi, entonces file.getName (). Subtring (file.getName (). IndexOf ("_")+1) puede obtener el a_fan_davi.avi parte*/ string realame = file.getName (). subString (file.getName (). indexOf ("_")+1); //file.getName () obtiene el nombre original del archivo. Este nombre es único, por lo que se puede usar como clave. RealName es el nombre procesado. Puede repetirse map.put (file.getName (), realName); }} public void dopost (httpservletRequest solicitud, respuesta httpservletResponse) arroja servletException, ioexception {doget (solicitud, respuesta); }} Aquí hablo brevemente sobre el método ListFile en ListFileServlet. El método ListFile se usa para enumerar todos los archivos en el directorio. El método ListFile utiliza la recursión. En el desarrollo real, definitivamente crearemos una tabla en la base de datos, que almacenará el nombre de archivo cargado y el directorio de almacenamiento específico del archivo. Podemos conocer el directorio de almacenamiento específico del archivo consultando la tabla, y no es necesario usar operaciones de recursión. Este ejemplo se debe a que la base de datos no almacena el nombre de archivo cargado y la ubicación de almacenamiento específica del archivo, y la ubicación de almacenamiento del archivo cargado se utiliza para romper el almacenamiento, por lo que se necesita recursión. Durante la recursión, el nombre de archivo obtenido se almacena en la colección de mapas que se pasa desde afuera al método de archivo de lista, por lo que podemos asegurarnos de que todos los archivos se almacenen en la misma colección de mapas.
Configurar listFileServlet en el archivo web.xml
<servlet> <servlet-name>ListFileServlet</servlet-name> <servlet-class>me.gacl.web.controller.ListFileServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ListFileServlet</servlet-name> <url-pattern>/servlet/ListFileServlet</url-pattern> </servlet-mapping>
La página ListFile.jsp que muestra el archivo descargado es el siguiente:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE HTML> <html> <head> <title>Download file display page</title> </head> <body> < href = "$ {downurl}"> descargar </a> <br/> </c: foreach> </body> </html> Al acceder al ListFileServlet, puede mostrar los recursos de archivo proporcionados a los usuarios para descargar en la página ListFile.jsp, como se muestra en la figura a continuación:
3.2. Implementar la descarga de archivos
Escriba un servlet para procesar descargas de archivos. El código para DownloadServlet es el siguiente:
paquete me.gacl.web.controller; import java.io.file; import java.io.fileInputStream; import java.io.ioException; import java.io.outputstream; import java.net.urlencoder; import javax.servlet.servletException; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; La clase pública descarga loadServlet extiende httpservlet {public void doget (httpservletRequest solicitud, respuesta httpservletResponse) lanza ServletException, ioexception {// Obtener el nombre del archivo para descargar la cadena filename = request.getParameter ("nombre de archivo"); //23239283-92489-avatar.avi filename = new String (FileName.getBytes ("ISO8859-1"), "UTF-8"); // Los archivos cargados se guardan en el subdirectorio de/Web-Inf/Suparte Directory String FilesCerooTpath = this.getServletContext (). GetRealPath ("/web-Inf/upload"); // Averigua el directorio donde el archivo se encuentra mediante el nombre del archivo String Path = findFilesApathByFileName (nombre de archivo, filesAverootPath); // Haga que el archivo se descargue archivo de archivo = nuevo archivo (ruta + "//" + nombre de archivo); // Si el archivo no existe if (! File.exists ()) {request.setAttribute ("Mensaje", "El recurso que desea descargar se ha eliminado!"); request.getRequestDIsPatcher ("/Message.jsp"). Foring (solicitud, respuesta); devolver; } // Procesar el nombre del archivo String RealName = FileName.Substring (FileName.IndexOf ("_")+1); // Establezca el encabezado de respuesta para controlar el navegador para descargar el archivo respuesta. // Lea el archivo que se descargará y guarda en el archivo de entrada de archivo FileInputStream in = new FileInputStream (Path + "//" + FileName); // Crear la transmisión de salida salida stream outs.getOutputStream (); // Cree el búfer de byte de búfer [] = nuevo byte [1024]; int len = 0; // bucle leer el contenido de la secuencia de entrada en el búfer mientras ((len = in.read (buffer))> 0) {// emite el contenido del búfer al navegador para realizar el archivo descargar out.write (buffer, 0, len); } // Cierre el archivo de entrada de archivo en.close (); // cierre la salida stream out.close (); } /*** @method: findFilesavePathByFileName* @Description: busque la ruta del archivo que se descargará a través del nombre del archivo y el directorio raíz de almacenamiento* @anthor: 发官网* @param nombre de archivo el nombre del archivo que se descargará* @param saveroootpath El directorio de la carga del directorio de la carga del archivo de la carga de almacenamiento. Cadena pública FindFilesAVePathByFileName (String FileName, String SaveroOtPath) {int hashcode = filename.hashcode (); int dir1 = hashcode & 0xf; // 0--15 int dir2 = (hashcode & 0xf0) >> 4; // 0-15 cadena dir = saverooTpath + "//" + dir1 + "//" + dir2; // cargar/2/3 cargar/3/5 archivo de archivo = nuevo archivo (dir); if (! file.exists ()) {// Crear directorio file.mkdirs (); } return dir; } public void dopost (httpservletRequest solicitud, respuesta httpservletreSponse) lanza ServletException, ioexception {doget (solicitud, respuesta); }}Configuración de descargaServlet en el archivo web.xml
<servlet> <servlet-name>DownLoadServlet</servlet-name> <servlet-class>me.gacl.web.controller.DownLoadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DownLoadServlet</servlet-name> <url-pattern>/servlet/DownLoadServlet</url-pattern> </servlet-mapping>
Haga clic en el Hyperlink [Descargar], envíe la solicitud al descarga y procese la descarga del archivo. El efecto de operación se muestra en la figura a continuación:
Desde los resultados en ejecución, podemos ver que nuestra función de descarga de archivos puede descargar archivos normalmente.
Lo anterior es la explicación más detallada de los ejemplos de carga y descarga de archivos introducidos por el editor (recomendado). 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!