Nota de estudio 4: Carga y descarga de archivos

Carga y descarga de archivos

Al navegar por Internet, encontraremos muchos casos de carga y descarga, como carga y descarga de imágenes. A continuación, echemos un vistazo a cómo el servlet implementa la carga y descarga.

Subir archivo

La carga del archivo implica la escritura de la página de primer plano y el código del lado del servidor de fondo, el primer plano envía el archivo, y el segundo plano acepta y guarda el archivo. Esta es una carga de archivo completa.

Página delantera:

Al cargar archivos, habrá una interfaz para cargar archivos. Primero, se requiere un formulario y el método de solicitud es POST; en segundo lugar, el enctype del formulario debe establecerse en "multipart / form-data" , es decir, enctype = "multipart / form- data" significa establecer el tipo de formulario en el formulario de carga de archivos. De forma predeterminada, este tipo de formulario es "application / x-www-from-urlencoded" y no se puede utilizar para cargar archivos. Solo cuando se utilizan datos de múltiples partes / formularios, el archivo de datos se puede transferir por completo.

<form action="uploadServlet" method="post" enctype="multipart/form-data">
    姓名:<input type="text" name="uname">
    文件:<input type="file" name="myfile">
    <button>提交</button>
</form>

Implementación de fondo:

Utilice la anotación @MultipartConfig para identificar un servlet como soporte para la carga de archivos. El servlet encapsula la solicitud POST multipart / form-data en un objeto Part y opera el archivo cargado a través del objeto Part .

package com.xxxx.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;

@WebServlet("/uploadServlet")
@MultipartConfig  //如果是文件上传,必须要加这个注解 让这个Servlet支持文件上传
public class UploadServlet extends HttpServlet {
    
    

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    

        System.out.println("文件上传...");

        //设置请求的编码格式
        request.setCharacterEncoding("utf-8");
        //获取普通表单项
        String uname = request.getParameter("uname");//参数为表单中表单元素的name属性值
        System.out.println("uname = " + uname);

        //获取part对象
        Part part = request.getPart("myfile");//参数为表单中file文件域的name属性值
        String fileName = part.getSubmittedFileName(); //获取提交过来的文件名
        System.out.println("filename = "+fileName);


        String filePath = request.getServletContext().getRealPath("/");//项目根目录
        System.out.println("filepath = "+filePath);
        //上传文件到指定目录(现在我们放在根目录下)
        part.write(filePath+"/"+fileName);

    }
}

Antes de la versión servlet3.0, debe usar el paquete jar de terceros commons-fileupload para cargar archivos. Servlet3.0 y superior tienen una API incorporada para cargar archivos. No hay paquete jar de terceros
servlet3.0 y superior. Guardar los archivos cargados en la parte En el ejemplo, el objeto de parte correspondiente se puede obtener de acuerdo con el nombre del control de formulario cargado a través del objeto de solicitud. Al mismo tiempo, también admite múltiples cargas de archivos
. La parte problemática es obtener el nombre del archivo , porque el archivo guardado no se puede guardar con el nombre de archivo en el momento de la carga. Debido a que tememos que muchas personas carguen el mismo nombre de archivo y se sobrescriban, generalmente es necesario establecer un nombre de archivo aleatorio que no se pueda repetir. Podemos usar UUID como el nombre del archivo. En cuanto al nombre del sufijo, debe obtenerse de acuerdo con el sufijo del archivo al cargar, parte El objeto en sí no almacena el nombre del archivo cargado. Necesitamos obtener el nombre del archivo de la información del encabezado de la solicitud. Cuando el navegador envía la solicitud de carga del archivo, el nombre del archivo se almacena en Content-Disposition en el Request Head, pero Content-Disposition tiene un valor. Además de la información del nombre del archivo, hay algunos otros información, por lo que la extensión del archivo solo se puede obtener mediante la interceptación de cadenas.

Disposición de contenido: datos de formulario; nombre = "archivo"; nombre de archivo = "prueba.txt"

El archivo se almacena en la carpeta de carga en el directorio raíz del proyecto actual del servidor. Obtenga el valor absoluto del servidor a través de req.getServletContext (). GetRealPath () y luego escriba el archivo cargado.

descarga de archivos

La descarga de archivos consiste en descargar los recursos del servidor al cliente local, hay dos formas, la primera es descargar a través de las características del propio hipervínculo y la segunda es descargar mediante operaciones de código.
La mayoría de las descargas de archivos del proyecto web no necesitan escribir código para lograrlo, solo a través del hipervínculo se puede lograr, es decir, a través del hipervínculo, escriba la ruta del archivo en la dirección de conexión, el navegador abrirá automáticamente el archivo, si es un texto normal, las imágenes y otros navegadores que pueden mostrar contenido directamente se pueden abrir y mostrar directamente, pero si es un archivo que el navegador no puede abrir, como rar, docx, exe, etc., luego, el navegador le pedirá que descargue el archivo modificado o use el archivo actual.

Descarga de hipervínculo :

Cuando usamos la etiqueta a en la página, esperamos poder saltar si queremos, pero cuando el hipervínculo encuentra un recurso que el navegador no reconoce, también se descargará automáticamente;
cuando encuentre un recurso que el navegador puede mostrar directamente, el navegador se mostrará de forma predeterminada, como txt, png, jpg, etc. Por supuesto, también puede especificar el navegador para descargar a través del atributo de descarga . Pero algunos navegadores no lo admiten.

<!-- 当超链接遇到不识别的资源时,会自动下载-->
<a href="test.zip">超链接下载</a>

Especifique el atributo de descarga para descargar:

<!--当超链接遇到浏览器识别的资源时,默认不会下载。通过download属性可进行强制下载-->
<a href="test.txt" download>超链接下载</a>

El atributo de descarga no necesita escribir ninguna información y el nombre de archivo predeterminado se usa automáticamente. Si se establece el valor del atributo de descarga, el valor establecido se utiliza como nombre de archivo. Cuando el usuario haga clic en el enlace, se descargará directamente.

Cabe señalar que si desea que el navegador pueda acceder a los recursos del proyecto, debe configurar la adición de recursos externos en Tomcat, de la siguiente manera:
Inserte la descripción de la imagen aquí

Descarga en segundo plano :

Pasos de implementación:

  1. Debe utilizar el método response.setContentType para establecer el valor del campo de encabezado Content-Type en un tipo MIME que el navegador no puede activar un programa de alguna manera para procesar, como "application / octet-stream" o "application / x-msdownload ".
  2. El valor del encabezado Content-Disposition debe establecerse como adjunto a través del método response.setHeader; nombre de archivo = nombre de archivo
  3. Lea el archivo descargado y llame al método response.getOutputStream para escribir el contenido del archivo adjunto al cliente.
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
    
    
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        System.out.println("文件下载...");
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");

        String fileName = request.getParameter("fileName");
        //判空 是否输入文件名
        if (fileName == null || "".equals(fileName.trim())){
    
    
            response.getWriter().write("请输入要下载的文件名!");
            response.getWriter().close();
            return;
        }
        //获取download文件夹的绝对路径(也就是存放项目资源的路径)
        String realPath = request.getServletContext().getRealPath("/download/");//获取download文件夹的绝对路径
        //通过路径获得这个file对象
        File file = new File(realPath+fileName);
        //判断这个文件是否存在并且是一个标准文件
        if (file.exists() && file.isFile()){
    
    
            //设置响应类型 浏览器无法使用某种方式激活某个程序来处理的 MIME 类型
            response.setContentType("application/octet-stream");
            //设置响应头
            response.setHeader("Content-Disposition","attachment;filename="+fileName);
            //得到这个文件的输入流
            InputStream in = new FileInputStream(file);
            //得到字节输出流
            ServletOutputStream out = response.getOutputStream();
            //定义byte数组
            byte[] bytes = new byte[1024];
            //定义长度
            int len = 0;
            //循环读取
            while((len = in.read(bytes)) != -1){
    
    
                out.write(bytes,0,len);
            }
            out.flush();
            out.close();
            in.close();

        }else{
    
    
            response.getWriter().write("文件不存在,请重试!");
            response.getWriter().close();
        }
    }
}

Enlace de conocimiento :

La disposición de contenido es una extensión del protocolo MIME, que indica al agente de usuario MIME cómo mostrar los archivos adjuntos. Cuando Internet Explorer recibe el encabezado, activa el cuadro de diálogo de descarga de archivos y su cuadro de nombre de archivo se llena automáticamente con el nombre de archivo especificado en el encabezado. (Tenga en cuenta que esto es por diseño; esta función no se puede usar para guardar documentos en la computadora del usuario sin preguntarle al usuario la ubicación para guardar).

Cuando el servidor envía un archivo al navegador del cliente, si es un tipo de archivo compatible con el navegador, generalmente el navegador lo abrirá de forma predeterminada, como txt, jpg, etc., que se mostrará directamente en el navegador. Si necesita pedirle al usuario que guarde, debe Para usar Content-Disposition para procesar, la clave es agregar un archivo adjunto:

Response.AppendHeader ("Contenido-Disposición", "archivo adjunto; nombre de archivo = NombreDeArchivo.txt");

Nota: De esta manera, el navegador le pedirá que guarde o abra, incluso si elige abrir, usará el programa asociado, como el Bloc de notas, para abrirlo en lugar de IE directamente.

Supongo que te gusta

Origin blog.csdn.net/qq_40492885/article/details/115265405
Recomendado
Clasificación