Servlet 3文件上传– @MultipartConfig
今天,我们将使用@MultipartConfig批注和javax.servlet.http.Part
查看Servlet 3文件上传示例。
Servlet 3文件上传
由于文件上传是Web应用程序中的常见任务,因此Servlet Specs 3.0为将文件上传到服务器提供了另外的支持,因此我们不必依赖任何第三方API。
在本教程中,我们将看到如何使用Servlet 3.0 API将文件上传到服务器。
MultipartConfig
我们需要使用MultipartConfig注释对File Upload处理程序servlet进行注释,以处理用于将文件上传到服务器的multipart/form-data请求。
MultipartConfig批注具有以下属性:
fileSizeThreshold:我们可以指定大小阈值,之后将文件写入磁盘。
大小值以字节为单位,因此1024 * 1024 * 10为10 MB。location:默认情况下文件存储的目录,默认值为""。
maxFileSize:允许上传文件的最大大小,其值以字节为单位。
默认值为-1L表示无限制。maxRequestSize:多部分/表单数据请求允许的最大大小。
默认值为-1L,表示无限制。
在Java Annotations Tutorial中阅读有关注释的更多信息。
零件界面
零件接口表示在multipart/form-data POST请求中收到的零件或者表单项。
一些重要的方法是getInputStream()
,write(String fileName)
,我们可以使用它们来读写文件。
HttpServletRequest的更改
HttpServletRequest中添加了新方法,以通过getParts()方法获取multipart/form-data请求中的所有部分。
我们可以使用getPart(String partName)
方法获得特定的零件。
让我们看一个简单的项目,在该项目中,我们将使用上述API方法来使用servlet上传文件。
我们的项目结构如下图所示。
HTML表格
我们有一个简单HTML页面,我们可以其中选择要上传的文件,然后向服务器提交请求以使其上传。
index.html
<html> <head></head> <body> <form action="FileUploadServlet" method="post" enctype="multipart/form-data"> Select File to Upload:<input type="file" name="fileName"> <br> <input type="submit" value="Upload"> </form> </body> </html>
文件上传Servlet
这是我们的文件上传Servlet实现。
FileUploadServlet.java
package com.theitroad.servlet; import java.io.File; import java.io.IOException; 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("/FileUploadServlet") @MultipartConfig(fileSizeThreshold=1024*1024*10, //10 MB maxFileSize=1024*1024*50, //50 MB maxRequestSize=1024*1024*100) //100 MB public class FileUploadServlet extends HttpServlet { private static final long serialVersionUID = 205242440643911308L; /** * Directory where uploaded files will be saved, its relative to * the web application directory. */ private static final String UPLOAD_DIR = "uploads"; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //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 the save directory if it does not exists File fileSaveDir = new File(uploadFilePath); if (!fileSaveDir.exists()) { fileSaveDir.mkdirs(); } System.out.println("Upload File Directory="+fileSaveDir.getAbsolutePath()); String fileName = null; //Get all the parts from request and write it to the file on server for (Part part : request.getParts()) { fileName = getFileName(part); part.write(uploadFilePath + File.separator + fileName); } request.setAttribute("message", fileName + " File uploaded successfully!"); getServletContext().getRequestDispatcher("/response.jsp").forward( request, response); } /** * Utility method to get file name from HTTP header content-disposition */ private String getFileName(Part part) { String contentDisp = part.getHeader("content-disposition"); System.out.println("content-disposition header= "+contentDisp); String[] tokens = contentDisp.split(";"); for (String token : tokens) { if (token.trim().startsWith("filename")) { return token.substring(token.indexOf("=") + 2, token.length()-1); } } return ""; } }
注意,使用@MultipartConfig批注为上传文件指定不同的大小参数。
我们需要使用请求标头的" content-disposition"属性来获取客户端发送的文件名,我们将使用相同的名称保存文件。
该目录位置是相对于我要将文件保存到的Web应用程序而言的,您可以将其配置为其他位置,例如在Apache Commons FileUpload示例中。
响应JSP
成功将文件成功上传到服务器后,将发送一个简单的JSP页面作为对客户端的响应。
response.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Upload File Response</title> </head> <body> <%-- Using JSP EL to get message attribute value from request scope --%> <h2>${requestScope.message}</h2> </body> </html>
部署描述符
web.xml文件中没有用于servlet文件上传的新内容,仅用于将index.html用作欢迎文件。
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>ServletFileUploadExample</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
现在,当我们运行该应用程序时,我们将获得以下页面作为响应。
日志将显示文件保存的目录位置以及内容处置标头信息。
Upload File Directory=/Users/hyman/Documents/workspace/j2ee/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/ServletFileUploadExample/uploads content-disposition header= form-data; name="fileName"; filename="IMG_2046.jpg"
我正在通过Eclipse运行Tomcat,因此文件位置是这样的。
如果通过命令行运行tomcat并通过将WAR文件导出到webapps目录中来部署应用程序,则会得到不同的结构,但结构清晰。