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日

相关文章

  • Java计算数学表达式代码详解

    Java计算数学表达式代码详解 简介 本文将介绍一种使用Java解析和计算数学表达式的方法。这种方法通过使用Java的ScriptEngine类中的JavaScript执行引擎来解析表达式并计算结果。 步骤 创建ScriptEngineManager对象和ScriptEngine对象 java ScriptEngineManager manager = ne…

    Java 2023年5月23日
    00
  • springMVC中的view视图详细解析

    在Spring MVC中,View是用于渲染模型数据的组件。在本文中,我们将详细介绍Spring MVC中的View视图,并提供两个示例来说明它们的使用。 ViewResolver 在Spring MVC中,ViewResolver是用于解析View的组件。它将逻辑视图名称解析为实际的View对象,并将其返回给DispatcherServlet。在Sprin…

    Java 2023年5月17日
    00
  • hadoop入门之通过java代码实现将本地文件上传到hadoop的文件系统

    下面是 “Hadoop入门之通过Java代码实现将本地文件上传到Hadoop的文件系统”的攻略。 步骤一:安装Hadoop 首先需要安装配置好Hadoop。具体安装过程这里不再赘述,可以参考官方文档:https://hadoop.apache.org/docs/r3.2.2/index.html 步骤二:引入Hadoop的依赖包 在java项目中使用Hado…

    Java 2023年5月20日
    00
  • 基于编译虚拟机jvm—openjdk的编译详解

    基于编译虚拟机jvm—openjdk的编译详解 在这篇攻略中,我们将通过使用编译虚拟机jvm-openjdk来编译代码。下面是详细的步骤: 步骤一:安装OpenJDK 在使用OpenJDK编译代码之前,我们需要先安装它。在Linux系统中,我们可以通过以下命令来安装OpenJDK: sudo apt-get install default-jdk 在Wind…

    Java 2023年5月26日
    00
  • Mybatis源码分析之插件模块

    “Mybatis源码分析之插件模块”是一篇深入剖析Mybatis插件模块的文章。总的来说,Mybatis插件模块的实现流程可以概括为下面四个核心类别:Interceptor、InterceptorChain、Plugin和Invocation。 Interceptor接口:插件必须实现的接口,提供了intercept()方法以便拦截Mybatis的方法调用。…

    Java 2023年6月1日
    00
  • centos下docker安装及springboot远程发布docker的方法

    安装docker的方法 安装Docker CentOS 7的默认镜像源没有包含Docker组件,因此需要手动安装。Docker仓库提供了一个安装脚本,只需输入以下命令: sudo yum install -y yum-utils device-mapper-persistent-data lvm2 \ && sudo yum-config-m…

    Java 2023年5月20日
    00
  • Springboot es包版本异常解决方案

    下面是“Springboot es包版本异常解决方案”的完整攻略,包含以下几部分内容: 问题描述 解决方案 示例说明 问题描述 使用 Spring Boot 时,如果要使用 Elasticsearch,一般会使用 Spring Data Elasticsearch(spring-boot-starter-data-elasticsearch),其中包含了 E…

    Java 2023年5月27日
    00
  • windows系统配置Java开发环境变量

    下面我将详细讲解在Windows系统上配置Java开发环境变量的完整攻略,包括以下内容: 下载Java JDK 安装Java JDK 配置Java环境变量 验证Java环境变量是否配置成功 下载Java JDK 首先,我们需要从Oracle官网(https://www.oracle.com/java/technologies/javase-downloads…

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