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 教程。