Jsp+Servlet实现文件上传下载 文件上传(一)

"JSP+Servlet实现文件上传下载",基本上可以分为文件上传和文件下载两个部分。下面详细讲解一下文件上传部分的实现过程。

文件上传实现

1. 文件上传表单页面

首先需要在页面上提供上传文件的表单。代码如下:

<form action="upload" method="post" enctype="multipart/form-data">
  请选择要上传的文件:<input type="file" name="file"><br/>
  <input type="submit" value="上传">
</form>

这个表单中,注意以下三点:

  • action 属性设为 "upload",表示文件上传的处理器的 url-pattern 属性值。
  • method 属性设为 "post",因为上传的文件可能比较大,需要使用 POST 方法上传。
  • enctype 属性设为 "multipart/form-data",表示 form 内容包含二进制数据。

2. 文件上传处理器

然后在 Servlet 中写文件上传处理器:

@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    // 检查是否为 multipart/form-data 表单
    if (!ServletFileUpload.isMultipartContent(req)) {
      resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Not a multipart request.");
      return;
    }

    // 配置上传参数
    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload uploader = new ServletFileUpload(factory);
    uploader.setFileSizeMax(1024 * 1024 * 100); // 100 MB
    uploader.setSizeMax(1024 * 1024 * 500); // 500 MB

    // 上传文件
    List<FileItem> items = uploader.parseRequest(req);
    for (FileItem item : items) {
      if (item.isFormField()) {
        // 处理表单字段(非文件字段)
      } else {
        // 处理文件字段
        String fileName = item.getName();
        String contentType = item.getContentType();
        long sizeInBytes = item.getSize();
        InputStream dataInput = item.getInputStream();
        // 处理文件
      }
    }

    // 发送响应
    resp.getWriter().print("Upload done.");
  }
}

这个文件上传处理器中,注意以下几点:

  • @WebServlet 注解的 url-pattern 属性值设为 "upload",与表单的 action 属性一致。
  • @MultipartConfig 注解表示该 Servlet 是一个多部分文件上传的 Servlet。
  • 检查是否为 multipart/form-data 表单。
  • 配置上传参数,比如文件大小限制。
  • 上传文件,使用 ServletFileUpload 类的 parseRequest() 方法解析 HttpServletRequest 中的数据,并返回一个 List<FileItem> 集合。
  • 遍历 List<FileItem>,检查每个 FileItem 是表单字段还是文件字段。
  • 如果是表单字段(非文件字段),可以通过 FileItem 的 getString() 或 getInputStream() 方法获取其值。
  • 如果是文件字段,可以通过 FileItem 的 getName()、getContentType()、getSize() 和 getInputStream() 方法获取文件的元数据及内容。

下面是一个示例,将上传的文件都保存到服务器本地文件系统中。

@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    // 检查是否为 multipart/form-data 表单
    if (!ServletFileUpload.isMultipartContent(req)) {
      resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Not a multipart request.");
      return;
    }

    // 配置上传参数
    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload uploader = new ServletFileUpload(factory);
    uploader.setFileSizeMax(1024 * 1024 * 100); // 100 MB
    uploader.setSizeMax(1024 * 1024 * 500); // 500 MB

    // 上传文件
    List<FileItem> items = uploader.parseRequest(req);
    String fileDir = "/path/to/your/upload/dir/";
    for (FileItem item : items) {
      if (item.isFormField()) {
        // 处理表单字段(非文件字段)
      } else {
        // 处理文件字段
        String fileName = item.getName();
        String contentType = item.getContentType();
        long sizeInBytes = item.getSize();
        InputStream dataInput = item.getInputStream();
        // 保存文件
        Path path = Paths.get(fileDir, fileName);
        Files.copy(dataInput, path, StandardCopyOption.REPLACE_EXISTING);
        // 处理文件
      }
    }

    // 发送响应
    resp.getWriter().print("Upload done.");
  }
}

上面这个例子中,上传的文件都会保存到文件系统的 "/path/to/your/upload/dir/" 文件夹下,如果该文件夹不存在会自动创建。路径可以根据实际情况修改。

3. 文件上传进度监控

文件上传过程中,用户可能需要看到上传的进度,提示上传过程是否成功。可以使用 Ajax 轮询的方式实现文件上传进度监控。以下是一个示例:

<script>
function pollProgress() {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseText != "") {
      var progress = JSON.parse(xhr.responseText);
      document.getElementById("progress").innerHTML = progress.percent + "%";
      if (progress.status == "IN_PROGRESS") {
        setTimeout(pollProgress, 1000); // 每秒轮询一次
      } else if (progress.status == "COMPLETED") {
        alert("Upload done.");
      } else if (progress.status == "FAILED") {
        alert("Upload failed.");
      }
    }
  };
  xhr.open("GET", "upload-progress", true);
  xhr.send();
}
</script>

<form onsubmit="pollProgress(); return false;">
  请选择要上传的文件:<input type="file" name="file"><br/>
  <input type="submit" value="上传">
</form>

<div id="progress"></div>

这个表单中,使用 onsubmit 事件调用 pollProgress() 函数,开始轮询上传进度。

@WebServlet("/upload-progress")
public class UploadProgressServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    HttpSession session = req.getSession();
    UploadProgress progress = (UploadProgress) session.getAttribute("uploadProgress");
    if (progress == null) {
      resp.getWriter().print("");
      return;
    }
    progress.updateStatus();
    String jsonString = progress.toJsonString();
    resp.setContentType("application/json");
    resp.setCharacterEncoding("UTF-8");
    resp.getWriter().print(jsonString);
  }
}

在之前的 UploadServlet 中,我们可以通过 HttpSession 把 UploadProgress 对象存储在 session 中,这样 UploadProgressServlet 可以在上传之外的任何时间获取到上传的进度,从而实现精确的轮询。

以下是 UploadProgress 的定义:

public class UploadProgress {
  private final long totalSize;
  private long uploadedSize;
  private String status;

  public UploadProgress(long totalSize) {
    this.totalSize = totalSize;
    this.uploadedSize = 0;
    this.status = "IN_PROGRESS";
  }

  public synchronized void addUploadedSize(long size) {
    uploadedSize += size;
  }

  public synchronized void updateStatus() {
    if (uploadedSize >= totalSize) {
      status = "COMPLETED";
    } else if (status.equals("IN_PROGRESS")) {
      status = "IN_PROGRESS";
    } else {
      status = "FAILED";
    }
  }

  public float getPercent() {
    return uploadedSize * 100.0F / totalSize;
  }

  public synchronized String toJsonString() {
    return String.format("{\"percent\": %.2f, \"status\": \"%s\"}", getPercent(), status);
  }
}

这个 UploadProgress 类,可以保存上传总大小、已上传大小、状态(IN_PROGRESS、COMPLETED、FAILED),以及提供一些操作方法,如更新已上传大小、更新状态、计算上传百分比和将 UploadProgress 对象转成 JSON 字符串等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Jsp+Servlet实现文件上传下载 文件上传(一) - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • Jenkins+maven持续集成的实现

    好的!下面就详细讲解一下“Jenkins+maven持续集成的实现”的完整攻略。 1. 简介 Jenkins是一个流行的开源持续集成工具,用于构建、自动化测试、部署、监控软件项目。而Maven则是一个流行的Java项目构建工具。利用Jenkins和Maven进行持续集成可以大大提高软件开发的效率和质量。 2. 实现过程 2.1 安装Jenkins 首先需要在…

    Java 2023年5月20日
    00
  • java 求解二维数组列最小值

    为了求解一个二维数组中每一列的最小值,我们可以采用以下步骤: 找到数组中每一列的最小值 将每一列的最小值存储到一个新数组中 以下是该过程的代码演示: public class MinInColumn { public static void main(String[] args) { int[][] array = {{1, 2, 3}, {4, 5, 6}…

    Java 2023年5月26日
    00
  • 通过Class类获取对象(实例讲解)

    通过Class类获取对象的步骤: 导入java.lang.reflect包中的Class类 使用Class类的forName()方法获取类对象 使用类对象的newInstance()方法创建实例 示例1: import java.lang.reflect.*; class Person { private String name; public void s…

    Java 2023年5月26日
    00
  • Linux小技巧分享之如何重新启动tomcat

    接下来我将详细讲解关于“Linux小技巧分享之如何重新启动tomcat”的完整攻略。 什么是Tomcat? Tomcat是一个广泛使用的开源Web服务器,具备Servlet和JSP规范,由Apache基金会维护。 为什么需要重新启动Tomcat? 当我们修改了Tomcat中的配置文件或者部署了新的代码后,我们需要重新启动Tomcat才能使这些变更生效。 如何…

    Java 2023年6月2日
    00
  • 使用纯java config来配置spring mvc方式

    使用纯Java配置Spring MVC的方式需要借助于Spring的WebApplicationInitializer接口。WebApplicationInitializer是一个接口,它被用来实现ServletContextInitializer,在servlet3.0+容器中被自动使用。在这里,我们将WebApplicationInitializer用于…

    Java 2023年5月16日
    00
  • Spring boot外部配置(配置中心化)详解

    Spring Boot 外部配置(配置中心化)详解 什么是 Spring Boot 外部配置? Spring Boot 提供了一种在不同环境下轻松配置应用程序的方法。我们可以将配置信息从代码中分离出来,采用外部化配置。该方法所需的参数可以存储在不同的位置中,如属性文件、YAML 文件、环境变量、数据库或远程配置服务器等,从而达到配置中心化的目的。这样做,可以…

    Java 2023年5月15日
    00
  • 使用Get方式提交数据到Tomcat服务器的方法

    下面是使用Get方式提交数据到Tomcat服务器的方法的完整攻略: 1. Get方式提交数据概述 在使用Get方式提交数据到Tomcat服务器之前,我们需要了解一下Get方式提交数据的基本概念,以及它和Post方式提交数据的区别。Get方式提交数据是指将数据塞入URL之中,浏览器将连接信息、参数信息和HTTP首部一起发送给服务器。相比较而言,Post方式提交…

    Java 2023年5月19日
    00
  • Spring Security十分钟入门教程

    Spring Security 十分钟入门教程 Spring Security 是一个基于 Spring 框架的安全框架,能够为 web 应用程序提供身份验证和授权的支持。 开始之前 在开始学习之前,需要具备以下知识: Spring 框架基础 Maven 项目管理工具 Spring Boot 基础知识 步骤 步骤一:创建一个 Spring Boot Web …

    Java 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部