Java Servlet 上传文件

Java Servlet 上传文件显示了如何使用 Servlet 技术在 Java Web 应用中上传单个文件。

Java Servlet

Servlet 是 Java 类,可响应特定类型的网络请求-最常见的是 HTTP 请求。 Java servlet 用于创建 Web 应用。 它们在 servlet 容器(例如 Tomcat 或 Jetty)中运行。 现代 Java Web 开发使用在 servlet 之上构建的框架。

HTML 表单编码类型

POST 请求有三种编码 HTML 表单方法:

  • 应用/ x-www-form-urlencoded
  • 多部分/表单数据
  • 文字/纯文字

application/x-www-form-urlencoded是默认编码。 这些值编码在由&分隔的键值元组中。 =字符用于键和值之间。 非字母数字字符采用百分比编码。 此编码类型不适用于二进制文件。

multipart/form-data用于非 acsii 数据和二进制文件。 input元素的type属性设置为file

text/plain用于调试。

Java Servlet 上传文件示例

在以下应用中,我们有一个 Web 表单来选择要上传到服务器的文件。 该表单调用 Java servlet,该 servlet 读取文件并将其保存到目录中。

上传目录

/var/www目录是 Debian Linux 中 Web 内容的标准目录。

$ ls -ld /var/www/upload/
drwxrwxr-x 2 www-data www-data 4096 Dec  3 14:29 /var/www/upload/

我们将文件上传到/var/www/upload目录。 www-data组中的用户可以修改目录文件。 因此,运行 Web 服务器的用户必须在此组中。

应用

这是一个 Maven Web 应用。 它部署在 Tomcat 上。

$ tree
.
├── nb-configuration.xml
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── zetcode
        │           └── FileUploadServlet.java
        └── webapp
            ├── index.html
            └── META-INF
                └── context.xml

这是项目结构。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zetcode</groupId>
    <artifactId>JavaServletFileUploadEx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>JavaServletFileUploadEx</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

这是 Maven POM 文件。 javax.servlet-api工件用于 servlet。 maven-war-plugin负责收集 Web 应用的所有工件依赖项,类和资源,并将它们打包到 Web 应用存档(WAR)中。

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/JavaServletFileUploadEx"/>

在 Tomcat context.xml文件中,我们定义了上下文路径。 它是 Web 应用的名称。

FileUploadServlet.java

package com.zetcode;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

@WebServlet(name = "FileUploadServlet", urlPatterns = {"/FileUploadServlet"},
      initParams = { @WebInitParam(name = "path", value = "/var/www/upload/") })
@MultipartConfig
public class FileUploadServlet extends HttpServlet {

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

        response.setContentType("text/plain;charset=UTF-8");    

        ServletOutputStream os = response.getOutputStream();

        ServletConfig sc = getServletConfig();
        String path = sc.getInitParameter("uploadpath");

        Part filePart = request.getPart("myfile");

        String fileName = filePart.getSubmittedFileName(); 
        InputStream is = filePart.getInputStream();

        Files.copy(is, Paths.get(path + fileName),
                StandardCopyOption.REPLACE_EXISTING);

        os.print("File successfully uploaded");
    }
}

FileUploadServlet将文件上传到/var/www/upload目录。

@WebServlet(name = "FileUploadServlet", urlPatterns = {"/FileUploadServlet"},
     initParams = { @WebInitParam(name = "uploadpath", value = "/var/www/upload/") })

使用@WebServlet批注,我们将 servlet 映射到/FileUploadServlet URL 模式,并定义了初始的uploadpath变量。

@MultipartConfig

servlet 也用@MultipartConfig装饰。 @MultipartConfig批注指示 servlet 期望使用multipart/form-data MIME 类型进行请求。

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

POST 请求由doPost()方法处理。

ServletOutputStream os = response.getOutputStream();

我们使用getOutputStream()方法获得 servlet 输出流。

ServletConfig sc = getServletConfig();
String path = sc.getInitParameter("uploadpath");

我们检索初始参数。 这是我们要上传文件的目录。

Part filePart = request.getPart("myfile");

使用getPart()方法检索文件部分。

String fileName = filePart.getSubmittedFileName(); 
InputStream is = filePart.getInputStream();

我们得到零件的文件名和输入流。

Files.copy(is, Paths.get(path + fileName),
        StandardCopyOption.REPLACE_EXISTING);

使用Files.copy(),将文件复制到目标目录。

os.print("File successfully uploaded");

最后,我们将消息写回客户端。

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Uploading a file</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css">
    </head>
    <body>
        <form class="pure-form pure-form-stacked" method="post" action="FileUploadServlet" 
              enctype="multipart/form-data">
            <fieldset>
                <legend>File:</legend>
                <input type="file" name="myfile">
                <button type="submit" class="pure-button pure-button-primary">Upload</button>
            </fieldset>
        </form>
    </body>
</html>

这是选择要上传文件的主页。 它包含一个 HTML 表单。 提交表单后,处理将发送到FileUploadServlet

<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css">

我们包括 Pure.css 库,用于创建负责任的页面。

<form class="pure-form pure-form-stacked" method="post" action="FileUploadServlet" 
        enctype="multipart/form-data">

method属性为 post,因为我们将数据发送到服务器。 action属性指定处理请求的 servlet 的名称。 enctype属性指定multipart/form-data编码类型,这是使用 HTML 格式上传文件所必需的。

<input type="file" name="myfile">

input标签的type属性使用户可以选择一个文件。

<button type="submit" class="pure-button pure-button-primary">Upload</button>

这是提交按钮。

您可能也对以下相关教程感兴趣:Java Log4j 教程Java Servlet RESTful 客户端Java servlet 图像教程Java 教程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程