ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# Java Servlet 上传文件 > 原文: [http://zetcode.com/articles/javaservletuploadfile/](http://zetcode.com/articles/javaservletuploadfile/) Java Servlet 上传文件显示了如何使用 Servlet 技术在 Java Web 应用中上传单个文件。 ## Java Servlet Servlet 是 Java 类,可响应特定类型的网络请求-最常见的是 HTTP 请求。 Java servlet 用于创建 Web 应用。 它们在 servlet 容器(例如 Tomcat 或 Jetty)中运行。 现代 Java Web 开发使用在 servlet 之上构建的框架。 ## HTML 表单编码类型 POST 请求有三种编码 HTML 表单方法: * `application/x-www-form-urlencoded` * `multipart/form-data` * `text/plain` `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 内容的标准目录。 ```java $ 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 上。 ```java $ tree . ├── nb-configuration.xml ├── pom.xml └── src └── main ├── java │ └── com │ └── zetcode │ └── FileUploadServlet.java └── webapp ├── index.html └── META-INF └── context.xml ``` 这是项目结构。 `pom.xml` ```java <?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` ```java <?xml version="1.0" encoding="UTF-8"?> <Context path="/JavaServletFileUploadEx"/> ``` 在 Tomcat `context.xml`文件中,我们定义了上下文路径。 它是 Web 应用的名称。 `FileUploadServlet.java` ```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`目录。 ```java @WebServlet(name = "FileUploadServlet", urlPatterns = {"/FileUploadServlet"}, initParams = { @WebInitParam(name = "uploadpath", value = "/var/www/upload/") }) ``` 使用`@WebServlet`批注,我们将 servlet 映射到`/FileUploadServlet` URL 模式,并定义了初始的`uploadpath`变量。 ```java @MultipartConfig ``` servlet 也用`@MultipartConfig`装饰。 `@MultipartConfig`批注指示 servlet 期望使用`multipart/form-data` MIME 类型进行请求。 ```java @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ``` POST 请求由`doPost()`方法处理。 ```java ServletOutputStream os = response.getOutputStream(); ``` 我们使用`getOutputStream()`方法获得 servlet 输出流。 ```java ServletConfig sc = getServletConfig(); String path = sc.getInitParameter("uploadpath"); ``` 我们检索初始参数。 这是我们要上传文件的目录。 ```java Part filePart = request.getPart("myfile"); ``` 使用`getPart()`方法检索文件部分。 ```java String fileName = filePart.getSubmittedFileName(); InputStream is = filePart.getInputStream(); ``` 我们得到零件的文件名和输入流。 ```java Files.copy(is, Paths.get(path + fileName), StandardCopyOption.REPLACE_EXISTING); ``` 使用`Files.copy()`,将文件复制到目标目录。 ```java os.print("File successfully uploaded"); ``` 最后,我们将消息写回客户端。 `index.html` ```java <!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`。 ```java <link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css"> ``` 我们包括 Pure.css 库,用于创建负责任的页面。 ```java <form class="pure-form pure-form-stacked" method="post" action="FileUploadServlet" enctype="multipart/form-data"> ``` `method`属性为 post,因为我们将数据发送到服务器。 `action`属性指定处理请求的 servlet 的名称。 `enctype`属性指定`multipart/form-data`编码类型,这是使用 HTML 格式上传文件所必需的。 ```java <input type="file" name="myfile"> ``` `input`标签的`type`属性使用户可以选择一个文件。 ```java <button type="submit" class="pure-button pure-button-primary">Upload</button> ``` 这是提交按钮。 在本教程中,我们展示了如何使用 Java Servlet 上传单个文件。 您可能也对以下相关教程感兴趣: [Java Servlet 分页](/articles/javaservletpagination/), [Java Log4j 教程](/java/log4j/), [Java Servlet RESTful 客户端](/articles/javaservletrestclient/), [Java `RequestDispatcher`](/java/requestdispatcher/) ,[从 Java servlet](/articles/javaservlettext/) , [Java servlet 图像教程](/articles/javaservletimage/)或 [Java 教程](/lang/java/)提供纯文本