java基于servlet实现文件上传功能解析

yizhihongxing

接下来我将详细讲解Java基于Servlet实现文件上传功能的完整攻略。该攻略分为以下几个步骤:

  1. 在HTML页面中添加文件上传表单
  2. 编写Servlet来处理文件上传请求
  3. 使用Apache的文件上传组件来解析文件上传请求
  4. 保存文件到指定位置并返回上传结果给用户

下面就来详细介绍这些步骤。

1. 在HTML页面中添加文件上传表单

首先,在你的HTML页面中添加一个文件上传表单,如下所示:

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

其中,action属性指定表单提交的目标URL,方法是POST,enctype属性是必要的,因为它指定要使用的编码类型,这里是multipart/form-data类型,这种类型可以支持文件上传。

2. 编写Servlet来处理文件上传请求

然后,我们需要编写一个Servlet来处理用户的文件上传请求。首先,需要在web.xml文件中添加一个Servlet的映射。

<servlet>
    <servlet-name>uploadServlet</servlet-name>
    <servlet-class>com.example.UploadServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>uploadServlet</servlet-name>
    <url-pattern>/upload</url-pattern>
</servlet-mapping>

其中,servlet-name指定了Servlet的名称,servlet-class则指定了Servlet的类路径。同时,servlet-mapping则用于将URL请求映射到Servlet。

接下来,我们就需要实现com.example.UploadServlet类,代码示例如下:

package com.example;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

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

    private static final long serialVersionUID = 1L;

    private static final String UPLOAD_DIRECTORY = "uploads"; // 上传目录
    private static final int MEMORY_THRESHOLD   = 1024 * 1024 * 3;  // 3MB
    private static final int MAX_FILE_SIZE      = 1024 * 1024 * 40; // 40MB
    private static final int MAX_REQUEST_SIZE   = 1024 * 1024 * 50; // 50MB

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 检查请求是否为multipart/form-data
        if (!ServletFileUpload.isMultipartContent(request)) {
            // 如果不是则停止
            PrintWriter writer = response.getWriter();
            writer.println("Error: 表单必须包含 enctype=multipart/form-data");
            writer.flush();
            return;
        }

        // 配置上传参数
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 设置内存临界值
        factory.setSizeThreshold(MEMORY_THRESHOLD);
        // 设置临时存储目录
        factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

        ServletFileUpload upload = new ServletFileUpload(factory);

        // 设置最大文件上传值
        upload.setFileSizeMax(MAX_FILE_SIZE);

        // 设置最大请求值 (包含文件和表单数据)
        upload.setSizeMax(MAX_REQUEST_SIZE);

        // 中文处理
        upload.setHeaderEncoding("UTF-8"); 

        // 构造临时路径来存储上传的文件
        // 这个路径相对当前应用的目录
        String uploadPath = getServletContext().getRealPath("/") + File.separator + UPLOAD_DIRECTORY;

        // 如果目录不存在则创建
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdir();
        }

        try {
            // 解析请求的内容提取文件数据
            @SuppressWarnings("unchecked")
            List<FileItem> formItems = upload.parseRequest(request);

            if (formItems != null && formItems.size() > 0) {
                // 迭代表单数据
                for (FileItem item : formItems) {
                    // 处理不在表单中的字段
                    if (!item.isFormField()) {
                        String fileName = new File(item.getName()).getName();
                        String filePath = uploadPath + File.separator + fileName;
                        File storeFile = new File(filePath);

                        // 保存文件到硬盘
                        item.write(storeFile);
                        request.setAttribute("message", "文件上传成功!");
                    }
                }
            }
        } catch (Exception ex) {
            request.setAttribute("message", "发生错误: " + ex.getMessage());
        }

        // 跳转到 message.jsp
        getServletContext().getRequestDispatcher("/message.jsp").forward(request, response);
    }
}

3. 使用Apache的文件上传组件来解析文件上传请求

上述代码使用了Apache的文件上传组件,org.apache.commons.fileupload。该组件提供了一个非常方便的API,可以处理文件上传请求。具体来说,以下是该攻略的一些关键部分:

  • DiskFileItemFactory: 文件上传的临时文件存储,它的默认构造函数将全部的二进制数据存储在内存,使用过多内存,因此使用setDefaultRepository将一部分存在硬盘上,该类还提供一个API来修改这个允许在内存中存储的数据的量。
  • ServletFileUpload: 文件上传的辅助类。ServletFileUpload包含一个FileItemFactory,它负责管理上传文件的存储,并将这些文件项存储在内存,或临时存储在磁盘中。
  • 构造实际的路径,并创建一个目录以存储上传文件。

在获取参数之前,我们将检查请求是否为multipart/form-data,这是我们是否真正处理文件上传的标志。我们也设置了一些UploadLimits来限制用户的上传大小。

然后,我们解析请求的文件和传输数据。如果是文件数据,我们将其保存到服务器的文件系统中。

4. 保存文件到指定位置并返回上传结果给用户

处理完文件上传请求后,我们需要将上传结果返回给用户,通常是返回一个确认消息。这时,我们需要将结果存储到request的属性中,然后使用JSP Page显示。

可以创建一个名为message.jsp的页面,其中包含以下代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>文件上传结果</title>
    </head>
    <body>
        <h1>文件上传结果</h1>
        <p>${message}</p>
    </body>
</html>

其中,${message}表示之前在Servlet中设置的message属性值,即文件上传结果。

至此,Java基于Servlet实现文件上传功能的完整攻略就介绍完了。

示例1

假设我们的项目名为FileUploadDemo,我们可以将以下示例代码保存为.jsp文件,然后部署到我们的Tomcat Web服务器上:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>文件上传示例</title>
    </head>
    <body>
        <h1>文件上传示例</h1>
        <form action="http://localhost:8080/FileUploadDemo/upload" method="post" enctype="multipart/form-data">
            <label for="file">文件:</label> <input type="file" name="file" id="file"><br>
            <input type="submit" name="submit" value="上传">
        </form>
    </body>
</html>

注意,文件上传表单的action属性应该设置为我们之前配置的上传Servlet路径,即/upload

示例2

除此之外,我们还可以使用Java内置的HttpURLConnection类来实现文件上传,示例代码如下:

package com.example;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class FileUploader {

    public static void main(String[] args) throws Exception {
        String serverUrl = "http://localhost:8080/FileUploadDemo/upload";
        String filePath = "/Users/user1/Documents/Book.pdf";

        File uploadFile = new File(filePath);
        String boundary = "-----------------------------" + System.currentTimeMillis();

        HttpURLConnection connection = (HttpURLConnection) new URL(serverUrl).openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        connection.setRequestProperty("User-Agent", "Java File Uploader/1.0");

        DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
        outputStream.writeBytes("--" + boundary + "\r\n");
        outputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + uploadFile.getName() + "\"\r\n");
        outputStream.writeBytes("Content-Type: application/octet-stream\r\n\r\n");

        FileInputStream inputStream = new FileInputStream(uploadFile);
        byte[] buffer = new byte[1024];
        int bytesRead = 0;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.writeBytes("\r\n--" + boundary + "--\r\n");

        inputStream.close();
        outputStream.flush();
        outputStream.close();

        System.out.println(connection.getResponseCode());
        System.out.println(connection.getResponseMessage());
    }
}

这个示例代码读取本地文件/Users/user1/Documents/Book.pdf并将其上传到指定的Web服务器。它使用了HttpURLConnection类来做Http传输并指定了请求方式POST、上传文件的Content-Type以及POST数据的分隔符。文件内容则通过DataOutputStream来写入RequestBody之内。值得注意的是,文件数据写入完成后,也要加上一个分隔符和标志结束。

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

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

相关文章

  • Java并行处理的实现

    Java并行处理的实现攻略 在Java中实现并行处理可以提高代码的性能,让代码的运行更快。本文将介绍Java中并行处理的实现攻略。 并行处理的概念和原理 并行处理是指多个任务同时执行,相互之间不受影响,可以提高代码的运行效率。Java中可以使用多线程实现并行处理。多线程是指同时运行多个线程,每个线程都独立运行,并且可以访问共享变量。Java中的线程是通过ja…

    Java 2023年5月18日
    00
  • Spring Boot 访问安全之认证和鉴权详解

    Spring Boot 访问安全之认证和鉴权详解 在Spring Boot应用中,实现访问安全、认证和鉴权是非常重要的。本文将详细讲解Spring Security的使用,使开发人员能够更好地掌握如何使用Spring Boot实现访问安全。 前置知识 在开始学习Spring Security之前,需要先掌握以下知识: Spring Boot的基础知识 Mav…

    Java 2023年5月20日
    00
  • JavaSpringBoot报错“ForbiddenException”的原因和处理方法

    原因 “ForbiddenException” 错误通常是以下原因引起的: 权限问题:如果您的权限存在问题,则可能会出现此错误。在这种情况下,需要检查您的权限并确保它们正确。 认证问题:如果您的认证存在问题,则可能会出现此错误。在这种情况下,需要检查您的认证并确保它们正确。 安全问题:如果您的安全存在问题,则可能会出现此错误。在这种情况下,需要检查您的安全并…

    Java 2023年5月4日
    00
  • Java生成日期时间存入Mysql数据库的实现方法

    非常感谢您对Java生成日期时间存入Mysql数据库的实现方法的关注。 下面是具体实现步骤和示例代码: 1. 准备工作 确保已经安装好了Java和Mysql,并且已经存在一个名为“test”的数据库。 导入mysql-connector-java-5.1.49-bin.jar包(版本可根据实际情况进行更换)。 2. 创建数据库表 创建一个名为“user”的表…

    Java 2023年5月20日
    00
  • bootstrap 下拉多选框进行多选传值问题代码分析

    下面给出“bootstrap下拉多选框进行多选传值问题代码分析”的完整攻略。 1. 背景 在使用bootstrap开发Web应用时,经常会使用下拉多选框进行多选,但如何将所选的值传递给后端服务器,还是一个值得探讨的问题。 2. 问题 bootstrap的下拉多选框有一个data-selected-text-format属性,它可以控制选中的值的格式,如可以将…

    Java 2023年6月15日
    00
  • Java 3年面试经验告诉你Mybatis是如何进行分页的

    我来帮你详细讲解一下关于“Java 3年面试经验告诉你Mybatis是如何进行分页的”的攻略。 简介 Mybatis 是一个非常流行的 Java 中间件,它可以帮助我们轻松地连接数据库并进行数据操作。在进行实际的开发过程中,数据量通常都是比较大的,因此我们需要对数据进行分页显示,这样才能更好的提高查询效率并减少资源消耗。 Mybatis 分页原理 Mybat…

    Java 2023年5月20日
    00
  • Android使用MediaCodec将摄像头采集的视频编码为h264

    下面是 Android 使用 MediaCodec 将摄像头采集的视频编码为 h.264 的攻略。 1. 前置知识 在开始本教程前,需要掌握以下知识: Android 摄像头基础使用 h.264 视频编码基础知识 2. 初始化 MediaCodec 首先,我们需要初始化 MediaCodec。在编码 h.264 视频时,我们将使用 Android 自带的 M…

    Java 2023年5月20日
    00
  • spring-boot使用AOP统一处理日志

    下面是详细讲解“spring-boot使用AOP统一处理日志”的完整攻略。 什么是AOP? AOP(Aspect Oriented Programming),中文翻译为面向切面编程,它允许我们通过预编译方式和运行期动态代理实现程序功能的统一维护。 AOP常见的应用场景 AOP的应用场景非常多,最常见的包括:日志记录、权限控制、事务管理、性能统计、异常处理等。…

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