Java Servlet文件上传
这个例子演示了如何使用javaservlet上传文件
将文件上载到javaeeservlets始终是可能的,但是需要付出很大的努力才能完成。apachefoundation甚至构建了一个名为Commons FileUpload的库,以使这个任务更容易实现。然而,Servlet3.0规范修复了这一差距,并且自从JavaEE6以来,多部分配置选项被添加到Servlet中,引入了
getPart
和
getParts
方法
HttpServletRequest
.
如果我们对使用WebServices将文件上载到服务器感兴趣,可以查看本教程。
Servlet文件上传示例
Servlet文件上载示例演示了MultipartConfig注释的用法,并使用户能够上载一个或者两个文件。
这个示例项目的结构非常简单。它由一个servlet文件组成
FileUploadServlet.java
,
pom.xml
在生成时处理依赖关系
web.xml
. 正如我们在Servlet注释示例中已经讨论过的,我们可以在注释和部署描述符之间选择来设置Servlet配置。此示例使用注释。
下图为项目结构图
Servlet文件上载项目结构
在马文家pom.xml文件我们需要声明的唯一依赖项是javax.servlet
<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>net.theitroad.tutorials</groupId> <artifactId>ServletFileUpload</artifactId> <version>1</version> <packaging>war</packaging> <name>ServletFileUpload</name> <url>https://theitroad.local</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>fileuploader</finalName> <sourceDirectory>src/main/java</sourceDirectory> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <warSourceDirectory>src/main/webapp</warSourceDirectory> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
文件上传servlet是我们项目的核心。它只有两种方法
goGet
,其中显示上载表单和和
doPost
,完成整个上传工作。
package net.theitroad.tutorials; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; 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 = "uploadServlet", urlPatterns = { "/upload" }, loadOnStartup = 1) @MultipartConfig(fileSizeThreshold = 6291456, //6 MB maxFileSize = 10485760L, //10 MB maxRequestSize = 20971520L //20 MB ) public class FileUploadServlet extends HttpServlet { private static final long serialVersionUID = 5619951677845873534L; private static final String UPLOAD_DIR = "uploads"; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); PrintWriter writer = response.getWriter(); writer.append("<!DOCTYPE html>\r\n") .append("<html>\r\n") .append(" <head>\r\n") .append(" <title>File Upload Form</title>\r\n") .append(" </head>\r\n") .append(" <body>\r\n"); writer.append("<h1>Upload file</h1>\r\n"); writer.append("<form method=\"POST\" action=\"upload\" ") .append("enctype=\"multipart/form-data\">\r\n"); writer.append("<input type=\"file\" name=\"fileName1\"<br<br\r\n"); writer.append("<input type=\"file\" name=\"fileName2\"<br<br\r\n"); writer.append("<input type=\"submit\" value=\"Submit\"\r\n"); writer.append("</form>\r\n"); writer.append(" </body>\r\n").append("</html>\r\n"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); //gets absolute path of the web application String applicationPath = request.getServletContext().getRealPath(""); //constructs path of the directory to save uploaded file String uploadFilePath = applicationPath + File.separator + UPLOAD_DIR; //creates upload folder if it does not exists File uploadFolder = new File(uploadFilePath); if (!uploadFolder.exists()) { uploadFolder.mkdirs(); } PrintWriter writer = response.getWriter(); //write all files in upload folder for (Part part : request.getParts()) { if (part != null && part.getSize() > 0) { String fileName = part.getSubmittedFileName(); String contentType = part.getContentType(); //allows only JPEG files to be uploaded if (!contentType.equalsIgnoreCase("image/jpeg")) { continue; } part.write(uploadFilePath + File.separator + fileName); writer.append("File successfully uploaded to " + uploadFolder.getAbsolutePath() + File.separator + fileName + "<br>\r\n"); } } } }
这个
@MultipatrtConfig
注解使servlet能够接受文件上传。有3个重要属性:
fileSizeThreshold–文件写入临时目录前要超过的文件大小。如果文件小于此阈值,则在请求完成之前,文件将驻留在内存中。
maxFileSize–这是允许上载的文件的最大大小。在上面的示例中,不允许用户上载大于10 MB的文件
maxRequestSize–是我们尝试用一个请求上传的所有文件大小的最大总和。在上面的例子中,我们将这个值设置为20MB,这意味着不管文件的数量是多少,我们总共可以上传20MB
我们可能需要指定或者不指定第四个属性。它被称为
location
它指向web容器应该存储临时文件的目录。但是,如果不指定此属性,容器将使用默认的临时文件夹。
我们超越
doGet
方法显示具有两个文件选择器字段的简单窗体。我们可能需要添加另外的输入字段,因为多部分附件允许这样做。
上载文件的窗体
在
doPost
方法首先构造要存储上载文件的文件夹的路径。比我们用的还要多
request.getParts()
迭代用户选择要上载的文件,并最终将它们存储到所需的位置。
构建和部署后,我们可以在浏览器中访问该应用程序:http://localhost:8080/fileuploader/upload