¿Qué es la carga de archivos?
La carga de archivos es para guardar información del usuario.
¿Por qué necesito subir un archivo?
Cuando un usuario se registra, el usuario puede necesitar enviar una foto. Entonces esta foto debe salvarse.
Subir componentes (herramientas) ¿Por qué necesitamos usar la herramienta de carga?
¿Por qué necesitamos cargar componentes? Cuando queremos obtener los datos del cliente, generalmente los obtenemos a través del método getParameter ().
Los datos de archivo cargados se dividen mediante un protocolo MIME, y el formulario está encapsulado en binario. En otras palabras: GetParameter () no puede obtener los datos del archivo cargado.
Veamos primero cómo las cargas de archivo HTTP traen datos con usted
Página JSP, Formulario debe especificar Enctype: multipart/formy-data
<form de acción = "$ {pageContext.request.contextPath}/servlet/uploadServlet1" enctype = "multipart/form-data" método = "post"> upload user: <input type = "text" name = "username"> <BR/> archivo de carga 1: <input type = "archivo" nombre = "archivo1"> <BR/> upload file 2: <inying type = "archivo de carga" name = "file2"> <br/> <input type = "subt" value = "enviar"> </form>Agarra del paquete HTTP
Intente obtener datos usando getParameter () en servlet
Cadena ss = request.getParameter ("UserName"); System.out.println (SS);No puede obtener los datos directamente usando GetParameter.
Entonces, ¿qué debemos hacer? ? ? ? El objeto de solicitud proporciona la transmisión de ServletInputStream para leernos los datos
Intentamos leer el archivo
ServletInputStream inputStream = request.getInputStream (); byte [] bytes = new Byte [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {System.out.println (new String (bytes, 0, len)); }Agregue un control de entrada adicional a la página JSP
<input type = "text" name = "contraseña">
El archivo de texto que cargué es 111111, y el efecto de lectura es el siguiente:
Ahora podemos leer los datos de los archivos de carga, pero ahora la pregunta es: ¿Cómo separar los datos cargados del archivo de los datos enviados al servidor? ? ? Hemos visto arriba en la imagen, se mezclan.
Es difícil separarse de acuerdo con nuestra práctica habitual, por lo que necesitamos cargar componentes
Hay dos tipos de componentes de carga de archivos [más operación] samrtupload [más operación] fileUpload
Para usar el componente FileUpload, debe importar dos paquetes JAR
Los pasos de desarrollo comunes-io Commons-Filead crean un objeto de fábrica de analizador [DiskFileItemFactory] Cree un analizador a través de la fábrica de analizador [ServletFileUpload] Llame al método de analizador para analizar el objeto de solicitud, obtenga todos los contenidos cargados [Lista] que atraviesa la lista, determine si cada objeto es un archivo cargado. Si se trata de un campo de formulario normal, obtenga el nombre del campo y el valor de campo. Si se trata de un archivo cargado, llame al método InputSteam para obtener la transmisión de entrada, lea los datos cargados rápidamente.
Prueba {// 1. Obtenga la fábrica de fábrica de fábrica analiza Factory = new DiskFileItemFactory (); // 2. Obtenga el analizador ServletFileUPLOAD SUPERD = new ServLetFileUpload (fábrica); // 3. Determine el tipo de formulario de carga if (! Upload.ismultipartContent (request)) {// cargar el formulario es una forma normal, luego obtenga los datos de la manera tradicional de devolver; } // Para cargar el formulario, llame al analizador para analizar la lista de datos cargada <StilEitem> list = upload.parserequest (solicitud); // fileItem // transfuse la lista y obtenga el objeto FileItem utilizado para encapsular el primer elemento de carga Elemento de datos del objeto FileItem para (fileItem item: list) {if (item.isformfield ()) {// Lo que obtiene es el elemento de entrada normal String name = item.getFieldName (); // Obtenga el nombre del valor de la cadena de elementos de entrada = item.getString (); System.out.println (nombre + "=" + valor); } else {// Obtener el elemento de entrada de carga String FileName = item.getName (); // Obtenga el nombre de archivo de carga c:/documentos y configuración/thinkpad/escritorio/1.txt filename = filename.substring (filename.lastindexof ("//")+1); InputStream in = item.getInputStream (); // obtener datos de carga int len = 0; byte buffer [] = nuevo byte [1024]; String SavePath = this.getServletContext (). GetRealPath ("/upload"); FileOutputStream out = new FileOutputStream (SavePath + "//" + FileName); // Escribir archivo en el directorio de carga while ((len = in.read (buffer))> 0) {out.write (buffer, 0, len); } in.close (); out.close (); }}} Catch (Exception e) {E.PrintStackTrace (); }¡Probar que tanto los campos ordinarios como los archivos cargados se pueden leer y obtener!
Smartupload
Para utilizar el componente SmartUpload, debe importar el paquete de desarrollo Smartupload.jar
Comienzo rápido
// Componente instanciado SmartUpload SmartUpload = new SmartUpload (); // Inicializar la operación de carga smartUpload.initialize (this.getServletConfig (), solicitud, respuesta); Pruebe {// Subiendo preparación smartupload.upload (); // Para datos ordinarios, es tan simple que el objeto de solicitud no puede obtener los parámetros enviados. Además, debe confiar en SmartUpload String Password = SmartUpload.getRequest (). GetParameter ("Passwase"); System.out.println (contraseña); // cargar para cargar la carpeta smartupload.save ("uploadfile"); } Catch (SmartuploadException e) {E.PrintStackTrace (); }prueba
Del mismo modo, podemos cargar archivos en la carpeta SubloadFile. ¡La cantidad de código se reduce mucho!
También puede obtener parámetros de campos normales
Cambié el nombre del archivo a código de confusión chino y código confuso chino para cargar datos, y era código confuso:
Los datos chinos enviados por el formulario también están confusos.
Como se mencionó anteriormente, la forma de cargar los datos del archivo se encapsula en binario, por lo que el uso de la solicitud para codificar los datos no funcionará para los datos enviados por el formulario.
FileUpload resuelve el código confusión
Usar FileUpload para resolver problemas confusos es muy simple
Resuelve el nombre de archivo chino confusión. Después de obtener el analizador, ¡simplemente establezca la codificación del analizador a UTF-8!
// Establecer la codificación de la carga fileupload.setheaderEncoding ("UTF-8");Resuelve los datos de forma confusa. Al obtener valores de formulario, use la codificación UTF-8 para obtenerlos.
Valor de cadena = fileitem.getString ("UTF-8");Efecto:
Smartupload resuelve el código confuso
Este componente es un poco problemático para resolver el problema del código confuso. Encontré varias soluciones en línea pero no pude encontrar una simple ...
Por lo tanto, si los datos no involucran chino, use el componente Smartupload, y si involucra datos chinos, ¡use el componente FileUpload!
Cargar múltiples archivos, agregar dinámicamente controles de carga
Supongamos que tengo múltiples archivos para cargar ahora, y el número de archivos para cargar es incierto. Entonces, ¿qué debemos hacer? ? ?
Es imposible para nosotros enumerar muchos controles para cargar archivos en la página, lo cual no es hermoso. Si el usuario no puede usar tantos controles, es un desperdicio.
Por lo tanto, queremos agregar dinámicamente controles para cargar archivos. Si el usuario también quiere cargar archivos, ¡solo necesita generar dinámicamente controles!
analizar
Para generar controles dinámicamente en la página, no es más que usar el código JavaScript.
Entonces, ¿qué hacemos? ?
Hagamos esto: cuando el usuario quiera cargar un archivo, haga clic en el botón y el botón vincula el evento para generar el control para la carga del archivo.
Para hacer más perfectamente, cada vez que se genera un control de carga de archivos, ¡también se proporciona un botón de eliminación para eliminar el control!
Deberíamos usar DIV para cargar los controles y eliminar los botones que queremos generar. Cuando el usuario hace clic para eliminar, debe ocultar el botón Eliminar y los controles de carga de archivos juntos. Entonces, ¡es mejor usar divs anidados!
Código de página Código:
<Able> <tr> <TD> User de carga: </td> <td> <input type = "text" name = "username"> </td> </tr> <tr> <tr> <td> agregue el archivo de carga </td> <td> <input type = "button" value = "agregue el archivo de carga"> </td> </tr> <tr> <tr> <viv> </biv> </td </td> </tr> </table>
Código JavaScript
<script type = "text/javaScript"> function adduploadFile () {// Generar el control de la carga de archivos var input = document.createElement ("entrada"); input.type = 'file'; input.name = 'FileName'; // Generar el botón Eliminar var del = document.createElement ("entrada"); del.type = 'botón'; del.value = 'eliminar'; // Generar Div Var interno InnerDiv = document.CreateElement ("Div"); // unir dos controles a InnerDiv.appendChild (entrada); innerdiv.appendchild (del); // Obtener el control DIV externo y vincular el DIV interno al DIV externo externo OutterDiv = document.getElementById ("archivo"); Outterdiv.AppendChild (InnerDiv); // BIND Event del.onclick = function delete () {// llamando al método de eliminación del div externo para matar el div interno this.parentnode.parentnode.removechild (this.parentNode); }} </script>Detalles de carga de archivo Si el tamaño del archivo cargado es mayor que el tamaño del archivo que establecemos, entonces el archivo usará un archivo temporal para guardar los datos cargados al cargar. Después de cargar, debemos eliminar el archivo temporal. La ubicación donde el servidor web no puede administrar el archivo de carga, de lo contrario, puede causar problemas de seguridad [otros pueden modificar el archivo de carga a través de medios] Si el nombre del archivo de carga es el mismo, el archivo de carga original se sobrescribirá. Queremos generar un nombre de archivo único. Si el número de usuarios es grande, hay muchos archivos cargados. Entonces no debemos guardar todos los archivos de carga en un directorio, lo que probablemente haga que el disco se bloquee. Por lo tanto, tenemos que dispersar los archivos cargados a diferentes directorios. analizar
El problema de eliminar archivos temporales es muy simple. Solo necesita llamar al método Delete () de FileItem después de que se completen todas las operaciones.
Para evitar que el archivo subido sea administrado por el servidor web, ¡podemos colocar la ubicación del archivo cargado en el directorio web-INF/!
Para el mismo nombre de archivo, podemos usar el nombre de archivo UUID+ cargado por el usuario como nuestro nombre de archivo Guardado cargado. Tal nombre de archivo es único.
Para romper los archivos cargados, necesitamos usar el algoritmo hashcode para romper.
Los cuatro bits inferiores generan un directorio de primer nivel 5-8 bits generan código de directorio de segundo nivel
Escribamos un código de archivo de carga relativamente completo
Use el algoritmo hashcode para romper los directorios guardados
String private MakedIrpath (string filename, ruta de cadena) {// Calcule los directorios primarios y secundarios a través del nombre del archivo int hashcode = filename.hashcode (); int dir1 = hashcode & 0xf; int dir2 = (hashcode & 0xf0) >> 4; Cadena dir = ruta + "//" + Dir1 + "//" + Dir2; // Si el directorio no existe, cree el archivo de directorio Archivo = nuevo archivo (Dir); if (! file.exists ()) {file.mkdirs (); } // Devuelve la ruta completa de retorno Dir; }Generar nombres de archivo únicos
String private MakefileName (String FileName) {// Use un bajo para separar el UUID y el nombre del archivo, y el nombre del archivo puede analizarse más adelante. return uuid.randomuuid (). toString () + "_" + nombre de archivo; }Código cargado
// crear fábrica diskfileitemFactory fábrica = new DiskFileItemFactory (); // Crear un analizador a través de la fábrica ServletFileUpload fileUpload = new ServletFileUpload (fábrica); // Establecer el código de carga fileUpload.setheaderEncoding ("UTF-8"); // juzga el tipo de formulario de carga if (! FileUpload.IsmultipartContent (request)) {// cargue el formulario como un formulario normal, luego obtenga los datos de la manera tradicional de devolver; } try {// analice el objeto de solicitud para obtener la lista [cargar todos los contenidos cargados] List <FileItem> list = fileUpload.Parserequest (solicitud); // viajar a través de la lista para determinar si el contenido cargado es un campo normal o un archivo de carga para (fileItem fileItem: list) {// Si es un elemento de entrada normal if (fileitem.isformfield ()) {// Obtener el nombre y el valor del elemento de entrada String name = fileItem.getFieldName (); Valor de cadena = fileitem.getString ("UTF-8"); System.out.println (nombre + "=" + valor); } else {// Si es un archivo de carga // obtener el nombre de carga [incluido el nombre de la ruta] string filename = fileItem.getName (); // interceptar el nombre del archivo FileName = FileName.Substring (FileName.lastIndexof ("//") + 1); // Generar un nombre de archivo único FileName = MakefileName (FileName); InputStream inputStream = fileItem.getInputStream (); // Obtenga la ruta del proyecto y escriba el archivo cargado en la ruta de cadena del proyecto = this.getServletContext (). GetRealPath ("/Web-Inf/uploadFile"); // Obtenga la cadena de ruta del directorio disperso realPath = MakedIrpath (nombre de archivo, ruta); FileOutputStream OutputStream = nuevo FileOutputStream (RealPath + "//" + FileName); byte [] bytes = new Byte [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {outputStream.Write (bytes, 0, len); } inputStream.Close (); outputStream.close (); // eliminar los datos del archivo temporal fileitem.delete (); }}} Catch (FileUploadException e) {E.PrintStackTrace (); }Efecto: el directorio se dividió con éxito y el nombre del archivo era único.
Enumere los archivos en el directorio cargado y proporcione descargas
Al explicar el objeto Response, se ha explicado la descarga del archivo. Esta vez escribiremos un pequeño caso para consolidar la descarga del archivo.
Hay 3 archivos en el directorio de carga
analizar
Primero, enumere todos los archivos en el directorio. Como necesitamos descargar el archivo de acuerdo con el nombre del archivo más adelante, usamos una colección de mapas para guardar todos los archivos
La parte de descarga también es muy simple. Encuentre el archivo correspondiente de acuerdo con el nombre del archivo y la ubicación del archivo de carga, léelo y escríbelo, y luego modifique el encabezado del mensaje para lograr la descarga.
Obtenga la ruta para cargar y cargar archivos, averigüe todos los archivos recursivamente (juzgando si es un archivo o es una salida recursiva), cargándolo en la colección de mapas y pase la colección de mapas a la recepción para mostrar cuando el usuario hace clic para descargar, y luego obtenga la ruta absoluta de acuerdo con el nombre original. Si el recurso existe, el usuario puede descargar el código y colocar todos los archivos almacenados en el directorio web-INF/ en la colección de mapas.
Solicitud de dopost voides protegido (httpservletRequest, httpservletResponse respuesta) lanza ServletException, ioexception {// obtiene el directorio donde el archivo cargado es cadena filePath = this.getServletContext (). getRealPath ("/web-inf/uploadfile"); Mapa map = nuevo hashmap (); // Use la recursión para obtener todos los archivos y agregarlos a la colección de mapas GetAllFiles (nuevo archivo (FilePath), MAP); request.setAttribute ("map", map); request.getRequestDIsPatcher ("/listFile.jsp"). Foring (solicitud, respuesta); } private void getAllfiles (archivo filePath, map map) {// Si no es un archivo, entonces es una carpeta if (! filePath.ISfile ()) {// enumere todos los archivos en la carpeta (tal vez un archivo, tal vez una carpeta) archivo [] archivos = filePath.ListFiles (); para (archivo de archivo: archivos) {// juzga el archivo obtenido (o carpeta) y getAllFiles (archivo, map); }} else {// Ingrese la instrucción Else, debe ser un archivo // obtener el nombre de archivo String FileName = FilePath.getName (). Substring (FilePath.getName (). LastIndexOf ("_") + 1); // Guardamos el nombre completo del archivo como la clave y el nombre del archivo como el valor en la colección de mapas map.put (filePath.getName (), nombre de archivo); }}Mostrar archivos descargables en la página JSP
<c: foreach elementos = "$ {map}" var = "me"> <c: url var = "url" value = "/downfileservlet"> <c: param name = "filename" value = "$ {me.key}"> </c: param> </c: url> $ {me.value} <a href = "$ {url}}" </a> <br> </c: foreach>Implementar el servlet descargado
Solicitud de dopost void protegida (httpservletRequest, httpservletreponse respuesta) lanza ServletException, ioexception {// obtiene el nombre completo de la cadena de archivo filename = request.getParameter ("nombre de archivo"); // Si se trata de datos chinos, se requiere transcodificación. FileName = new String (FileName.getBytes ("ISO8859-1"), "UTF-8"); // Obtenga la ubicación donde el archivo se guarda la ruta de cadena = this.getServletContext (). GetRealPath ("/Web-Inf/uploadFile"); // El archivo se guarda a través del nombre del archivo por hashcode, y el archivo se obtiene a través de la cadena de nombre del archivo FileRealPath = MakefilePath (nombre de archivo, ruta); System.out.println (FileRealPath); // juzga si el archivo existe archivo archivo = nuevo archivo (filrealPath); if (! file.exists ()) {request.setAttribute ("Mensaje", "¡El recurso que desea descargar no existe!"); request.getRequestDIsPatcher ("/Message.jsp"). Foring (solicitud, respuesta); devolver ; } // existir // Leer el archivo y escribir los datos en el navegador FileInputStream InputStream = new FileInputStream (FileRealPath); byte [] bytes = new Byte [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {respuesta.getOutputStream (). Write (bytes, 0, len); } inputStream.Close (); // Establezca el encabezado del mensaje para decirle al navegador que este es el nombre del archivo descargado name = filename.substring (filename.lastindexof ("_") + 1); Respuesta.Setheader ("Disposición de contenido", "Adjunto; FileName =" + Urlencoder.encode (nombre, "UTF-8")); } private String MakeFilePath (String FileName, String Path) {int hashcode = filename.hashCode (); int dir1 = hashcode & 0xf; int dir2 = (hashcode & 0xf0) >> 4; Cadena dir = ruta + "//" + dir1 + "//" + dir2 + "//" + nombre de archivo; Diren de regreso; }Efecto
Si hay algún error en el artículo, corregirme y todos se comunicarán entre sí. Gracias por su apoyo a Wulin.com.