文件的上传和下载

文件的上传

  文件上传涉及前台页面的编写和后台服务器端代码的编写,前台发送文件,后台接收并保存文件,这才是一个完整的文件上传。

前台页面

  做文件上传的时候,会有一个上传文件的界面,首先我们需要一个表单,并且表单的请求方式是POST;其次我们的form表单的entype必须设为"multipart/form-data",即entype="multipart/form-data"意思是设置表单的类型为文件上传表单。默认情况下这个表单的类型是application/x-www-form-urlencoded,不能用于文件的上传。只有使用了multipart/form-data才能完整地传递文件数据。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>upload</title>
</head>
<body>
   <form action="upload" method="post" enctype="multipart/form-data">
       Name : <input type="text" name="usrname"><br>
       File : <input type="file" name="afile"><br>
       <button type="submit">upload</button>
   </form> 
</body>
</html>

后台实现

  使用注解@MultipartConfig将一个Servlet标识为支持文件上传。Servlet将multipart/form-data的POST请求封装成Part,通过Part对上传文件进行操作。

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;

import java.io.IOException;

@WebServlet("/upload")
@MultipartConfig
public class Upload extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("file uploading...");

        req.setCharacterEncoding("UTF-8");  //设置编码

        String name = req.getParameter("usrname");
        Part part = req.getPart("afile");

        String fileName = part.getSubmittedFileName();   //获取上传文件名称
        String filePath =  req.getServletContext().getRealPath("/");

        part.write(filePath + '/' + fileName); // tomcat10 在filePath中已经自带'/'

        System.out.println("saving : " + filePath + "/" + fileName);
    }
}

文件的下载

  文件下载,即将服务器上的资源下载(拷贝)到本地,我们可以通过两种方式下载。

超链接下载

  当我们在HTML或JSP页面中使用a标签时,愿意是希望进行跳转,但当超链接遇到浏览器不识别的资源时会自动下载;当浏览器能够直接显示的资源,浏览器就会默认显示出来,比如txt、png、jpg等。当然我们也可以通过download属性规定浏览器进行下载,但有的浏览器不支持。

<!--默认下载-->
<!--当超链接遇到浏览器不识别的资源时,会自动下载-->
<a href="text.txt">超链接下载</a>

<!--指定download属性下载-->
<!-- 当超链接遇到浏览器识别的资源时,默认不会下载。通过download属性下载-->
<a href="text.txt" download="whatis.txt">超链接下载</a>

  download属性可以不写任何信息,会自动使用默认文件名。如果设置了download属性的值,则使用设置的值作为文件名。当用户打开浏览器点击超链接,就会下载此文件。

后台实现下载

步骤

  1. 需要通过resp.setContentType()方法设置Content-type头字段的值,为浏览器无法使用某种方式或激活某个程序来处理MIME类型,例如application/octet-streamapplication/x-msdownload
  2. 需要通过resp.setHeader方法设置Content-Disposition头的值为attchment;filename=文件名 3.读取文件,调用resp.getOutputStream方法向客户端写入附件内容。
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;

@WebServlet("/download")
public class Download extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");  //设置客户端编码
        resp.setContentType("text/html;charset=UTF-8");//设置返回编码
        String fileName = req.getParameter("target");//获取文件名
        if (fileName == null || "".equals(fileName.trim())) //.trim去除首尾空格
        {
            resp.getWriter().write("fileName can't be null");
            return;
        }

        String path = getServletContext().getRealPath("/");
        File file = new File(path + fileName);

        if (file.exists() && file.isFile())
        {
            resp.setContentType("application/octet-stream");//设置文件类型为浏览器无法识别
            resp.setHeader("content-Disposition", "attchment;filename=" + fileName); //返回头中写如文件名

            InputStream is = new FileInputStream(file);

            ServletOutputStream os = resp.getOutputStream();

            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = is.read(bytes)) != -1)
            {
                os.write(bytes, 0, len);
            }

            is.close();
            os.close();

        } else {
            resp.getWriter().write("The file does not exists, please try again.");
        }
    }
}