JavaWeb实现文件上传下载功能实例解析

JavaWeb实现文件上传下载功能实例解析

一、文件上传

文件上传是指将本地机器上的文件通过网络传输到远程服务器上的过程。在JavaWeb中,可以使用Servlet实现文件上传功能。

在上传文件之前,需要先创建一个表单,让用户选择需要上传的文件。具体操作如下:

  1. 在HTML中创建一个表单,指定表单的enctype属性值为"multipart/form-data",表单中包含一个file类型的input元素:
<form action="uploadServlet" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="上传">
</form>
  1. 在Servlet中处理上传的文件。获取上传的文件需要使用到requset.getParts()方法。该方法返回一个Part的集合,我们可以使用for循环对其中的每个Part进行处理。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");

    Collection<Part> parts = request.getParts();
    for (Part part : parts) {
        String fileName = getFileName(part);
        if (fileName != null && !"".equals(fileName)) {
            part.write("D:/" + fileName); // 将上传的文件保存到D盘目录下
        }
    }
}

private String getFileName(Part part) {
    String contentDisposition = part.getHeader("Content-Disposition");
    if (contentDisposition == null) {
        return null;
    }
    String[] attrs = contentDisposition.split(";");
    for (String attr : attrs) {
        if (attr.trim().startsWith("filename=")) {
            return attr.substring(attr.indexOf('=') + 1).trim().replace("\"", "");
        }
    }
    return null;
}

二、文件下载

文件下载是指将服务器上的文件发送到客户端,让客户端可以下载到本地机器上。在JavaWeb中,可以使用Servlet实现文件下载功能。

在下载文件之前,需要先在Servlet中指定要下载的文件,并将该文件的InputStream中的数据写入到ServletOutputStream中,最后发送给客户端即可。具体操作如下:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String filePath = "D:/test.txt"; // 下载的文件路径
    File file = new File(filePath);
    if (!file.exists()) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
        bis = new BufferedInputStream(new FileInputStream(file));
        bos = new BufferedOutputStream(response.getOutputStream());
        byte[] buffer = new byte[1024];
        int len;
        while ((len = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
    } finally {
        if (bis != null) {
            bis.close();
        }
        if (bos != null) {
            bos.close();
        }
    }
}

以上是JavaWeb实现文件上传下载功能的完整攻略,以下是两个实用的案例:

示例1:上传图片,并将图片展示在页面上

HTML代码

<form action="uploadServlet" method="post" enctype="multipart/form-data">
    <input type="file" name="image" accept="image/png, image/jpeg, image/gif">
    <input type="submit" value="上传">
</form>

<!-- 展示图片 -->
<img src="">

<script>
    // 图片上传成功后,将该图片展示在页面上
    function handleFile() {
        var file = document.querySelector('input[type=file]').files[0];
        var reader = new FileReader();
        reader.onload = function(event) {
            document.querySelector('img').setAttribute('src', event.target.result);
        };
        reader.readAsDataURL(file);
    }
    document.querySelector('input[type=file]').addEventListener('change', handleFile);
</script>

Servlet代码:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Collection<Part> parts = request.getParts();
    for (Part part : parts) {
        if ("image".equals(part.getName())) {
            String fileName = getFileName(part);
            if (fileName != null && !"".equals(fileName)) {
                part.write("D:/" + fileName); // 将上传的图片保存到D盘目录下
                String imageUrl = "/images/" + fileName;
                response.getWriter().write(imageUrl);
            }
        }
    }
}

private String getFileName(Part part) {
    String contentDisposition = part.getHeader("Content-Disposition");
    if (contentDisposition == null) {
        return null;
    }
    String[] attrs = contentDisposition.split(";");
    for (String attr : attrs) {
        if (attr.trim().startsWith("filename=")) {
            return attr.substring(attr.indexOf('=') + 1).trim().replace("\"", "");
        }
    }
    return null;
}

示例2:下载文件并限制下载速度

Servlet代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String filePath = "D:/test.pdf"; // 下载的文件路径
    File file = new File(filePath);
    if (!file.exists()) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));

    // 控制下载速度
    response.setBufferSize(4096); // 每次读取的字节数
    long fileSize = file.length(); // 文件总大小
    long start = 0;
    long end = fileSize - 1;
    String range = request.getHeader("Range");
    if (range != null && range.matches("^bytes=\\d*-\\d*$")) {
        String[] bytes = range.substring(6).split("-");
        start = Long.parseLong(bytes[0]);
        end = Long.parseLong(bytes.length > 1 && !"".equals(bytes[1]) ? bytes[1] : (fileSize - 1) + "");
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
    }
    response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileSize);

    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
        bis = new BufferedInputStream(new FileInputStream(file));
        bis.skip(start);
        bos = new BufferedOutputStream(response.getOutputStream());
        byte[] buffer = new byte[4096];
        long length = end - start + 1;
        int len;
        long count = 0;
        long time = System.currentTimeMillis();
        while ((len = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
            count += len;
            if (count >= length) {
                break;
            }
            long nowTime = System.currentTimeMillis();
            if (nowTime - time >= 1000) {
                synchronized (this) {
                    try {
                        wait(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                time = nowTime;
            }
        }
    } finally {
        if (bis != null) {
            bis.close();
        }
        if (bos != null) {
            bos.close();
        }
    }
}

其中,通过设置response的BufferSize属性来控制每次读取的字节数,在循环读取文件内容时,控制每秒输出文件的字节数来控制下载速度,使用synchronized来防止CPU瞎忙。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaWeb实现文件上传下载功能实例解析 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Spring Boot Security配置教程

    下面我将详细讲解如何配置Spring Boot项目的Spring Security。首先,我们需要按照以下步骤进行配置: 步骤一:pom.xml文件中添加依赖 首先,我们需要在pom.xml文件中添加Spring Security的依赖。示例代码如下: <dependency> <groupId>org.springframework…

    Java 2023年5月15日
    00
  • Java 创建线程的3种方法及各自的优点

    下面我将为您详细讲解“Java 创建线程的3种方法及各自的优点”的完整攻略。 Java 创建线程的3种方法及各自的优点 在Java中,创建线程有三种常用的方法,分别为继承Thread类、实现Runnable接口和实现Callable接口。各自的优点如下: 继承Thread类 继承Thread类创建线程是最简单的方法,只需要重写Thread类的run方法即可。…

    Java 2023年5月18日
    00
  • 你可能从未使用过的11+个JavaScript特性(小结)

    下面是详细讲解“你可能从未使用过的11+个JavaScript特性(小结)”的攻略。 介绍 本文将讲解11+个在JavaScript中常被忽略的特性。包括可选链操作符、空合并运算符、BigInt、Promise.allSettled()、Array.flat()、Array.flatMap()、Object.fromEntries()、String.trim…

    Java 2023年5月26日
    00
  • 一篇超详细的Spring Boot整合Mybatis文章

    Spring Boot整合MyBatis完整攻略 Spring Boot是一个快速开发框架,可以帮助开发人员快速构建Web应用程序。在Spring Boot中,整合MyBatis可以帮助我们更方便地操作数据库。本文将介绍如何在Spring Boot中整合MyBatis,并提供两个示例。 整合MyBatis 在Spring Boot中整合MyBatis需要以下…

    Java 2023年5月15日
    00
  • springboot返回modelandview页面的实例

    首先,我们需要了解什么是 Spring Boot。Spring Boot 是 Spring 家族开源的轻量级 Web 开发框架,它简化了 Spring 繁琐的配置,使开发者能够更加专注于业务逻辑的实现。 在 Spring Boot 中,我们可以通过创建一个控制器类来处理请求并返回响应,其中返回 ModelAndView 类型的对象可以用于处理页面渲染。 以下…

    Java 2023年6月15日
    00
  • SpringBoot详解执行过程

    Spring Boot是一种基于Spring框架的轻量级开发框架,它可以使Spring应用的开发更快、更容易,更有生产力。在了解Spring Boot的执行过程之前,我们需要了解Spring Boot的主要特点: 简化了Spring应用的开发过程,减少了开发人员的配置工作。 自动配置Spring环境,包括数据库、缓存等。 提供了一组开箱即用的功能,比如:监控…

    Java 2023年5月15日
    00
  • Python漏洞验证程序Poc利用入门到实战编写

    Python漏洞验证程序Poc(Proof of Concept)利用入门到实战编写的攻略主要包含以下几个步骤: 1. 确定漏洞类型及目标 在编写Poc的前提下,需要先确定目标攻击对象以及攻击的漏洞类型。例如,确定攻击Python web应用程序中的SQL注入漏洞。 2. 进行漏洞测试 在确定漏洞类型之后,需要利用工具或手动方式进行漏洞测试确认漏洞是否存在以…

    Java 2023年5月20日
    00
  • 小程序关于请求同步的总结

    针对“小程序关于请求同步的总结”的完整攻略,我将在以下几个方面进行详细讲解: 同步请求与异步请求的区别与应用场景 如何发起同步请求 同步请求的注意事项 1. 同步请求与异步请求的区别与应用场景 同步请求和异步请求都是构成 HTTP 协议的方式之一。同步请求和异步请求的主要区别在于:同步请求会阻塞主进程,直到响应结果返回;而异步请求则不会,主进程会继续执行后续…

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