Servlet 3 文件上传 - @MultipartConfig,部分

今天,我们将使用 @MultipartConfig 注释和 javax.servlet.http.Part 查看 Servlet 3 文件上传示例. 有一段时间我写了一篇关于 Servlet 文件上传的文章,我使用了 Apache FileUpload API,但在这里我们将使用 Servlet 3 文件上传功能。

3 檔案上傳

由于文件上传是Web应用中常见的任务,Servlet Specs 3.0为上传文件到服务器提供了额外的支持,我们不必依赖于任何第三方API。

多元化

我们需要注释 File Upload handler servlet 使用 MultipartConfig 注释来处理用于将文件上传到服务器的 multipart/form-data 请求。

  • fileSizeThreshold:我们可以指定文件将被写入磁盘的尺寸门槛。 尺寸值为字节,所以1024102410是10 MB
  • 位置:文件将被默认存储的目录,默认值是``。
  • maxFileSize:允许上传文件的最大尺寸,其值为字节。 默认值是 -1L 意味着无限
  • maxRequestSize:允许多部分/形式数据请求的最大尺寸。 默认值是 -1L 意味着无限

阅读有关注释的更多信息在 [Java 注释教程]( / 社区 / 教程 / Java 注释)。

部分接口

Part interface代表一部分或表单项目,它是在多部分/form-data POST 请求中接收的。

HttpServlet请求变更

New methods got added in HttpServletRequest to get all the parts in multipart/form-data request through getParts() method. We can get a specific part using getPart(String partName) method. Let's see a simple project where we will use above API methods to upload file using servlet. Our project structure will look like below image. Servlet 3 File Upload, @MultipartConfig, javax.servlet.http.Part

HTML 格式

我们有一个简单的HTML页面,我们可以选择要上传的文件,并向服务器提交请求,以便上传。

 1<html>
 2<head></head>
 3<body>
 4<form action="FileUploadServlet" method="post" enctype="multipart/form-data">
 5Select File to Upload:<input type="file" name="fileName">
 6<br>
 7<input type="submit" value="Upload">
 8</form>
 9</body>
10</html>

文件上传服务器

这里是我们的 File Upload Servlet 实现。 FileUploadServlet.java

 1package com.journaldev.servlet;
 2
 3import java.io.File;
 4import java.io.IOException;
 5
 6import javax.servlet.ServletException;
 7import javax.servlet.annotation.MultipartConfig;
 8import javax.servlet.annotation.WebServlet;
 9import javax.servlet.http.HttpServlet;
10import javax.servlet.http.HttpServletRequest;
11import javax.servlet.http.HttpServletResponse;
12import javax.servlet.http.Part;
13
14@WebServlet("/FileUploadServlet")
15@MultipartConfig(fileSizeThreshold=1024*1024*10, 	// 10 MB 
16                 maxFileSize=1024*1024*50,      	// 50 MB
17                 maxRequestSize=1024*1024*100)   	// 100 MB
18public class FileUploadServlet extends HttpServlet {
19
20    private static final long serialVersionUID = 205242440643911308L;
21    
22    /**
23     * Directory where uploaded files will be saved, its relative to
24     * the web application directory.
25     */
26    private static final String UPLOAD_DIR = "uploads";
27
28    protected void doPost(HttpServletRequest request,
29            HttpServletResponse response) throws ServletException, IOException {
30        // gets absolute path of the web application
31        String applicationPath = request.getServletContext().getRealPath("");
32        // constructs path of the directory to save uploaded file
33        String uploadFilePath = applicationPath + File.separator + UPLOAD_DIR;
34
35        // creates the save directory if it does not exists
36        File fileSaveDir = new File(uploadFilePath);
37        if (!fileSaveDir.exists()) {
38            fileSaveDir.mkdirs();
39        }
40        System.out.println("Upload File Directory="+fileSaveDir.getAbsolutePath());
41
42        String fileName = null;
43        //Get all the parts from request and write it to the file on server
44        for (Part part : request.getParts()) {
45            fileName = getFileName(part);
46            part.write(uploadFilePath + File.separator + fileName);
47        }
48
49        request.setAttribute("message", fileName + " File uploaded successfully!");
50        getServletContext().getRequestDispatcher("/response.jsp").forward(
51                request, response);
52    }
53
54    /**
55     * Utility method to get file name from HTTP header content-disposition
56     */
57    private String getFileName(Part part) {
58        String contentDisp = part.getHeader("content-disposition");
59        System.out.println("content-disposition header= "+contentDisp);
60        String[] tokens = contentDisp.split(";");
61        for (String token : tokens) {
62            if (token.trim().startsWith("filename")) {
63                return token.substring(token.indexOf("=") + 2, token.length()-1);
64            }
65        }
66        return "";
67    }
68}

请注意使用 @MultipartConfig 注释来指定上传文件的不同大小参数. 我们需要使用请求标题内容分布属性来获得客户端发送的文件名,我们将以相同的名称保存文件。

JSP 回应

一个简单的 JSP 页面,一旦文件被成功上传到服务器后,将作为响应发送给客户端。

 1<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 2    pageEncoding="ISO-8859-1"%>
 3<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
 4    "https://www.w3.org/TR/html4/loose.dtd">
 5<html>
 6<head>
 7<title>Upload File Response</title>
 8</head>
 9<body>
10    <%-- Using JSP EL to get message attribute value from request scope --%>
11    <h2>${requestScope.message}</h2>
12</body>
13</html>

部署描述

在 web.xml 文件上传的 servlet 文件中没有什么新鲜事,它只是用来将 index.html 作为欢迎文件。

1<?xml version="1.0" encoding="UTF-8"?>
2<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">
3  <display-name>ServletFileUploadExample</display-name>
4  <welcome-file-list>
5    <welcome-file>index.html</welcome-file>
6  </welcome-file-list>
7</web-app>

Now when we run the application, we get following pages as response. Servlet 3 File Upload HTML Servlet 3 File Upload Success The logs will show the directory location where file is saved and content-disposition header information.

1Upload File Directory=/Users/pankaj/Documents/workspace/j2ee/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/ServletFileUploadExample/uploads
2content-disposition header= form-data; name="fileName"; filename="IMG_2046.jpg"

如果你运行 tomcat 通过命令行,并通过将应用程序导出为 WAR 文件到 webapps 目录中,你会得到不同的结构,但一个清晰的。

下载Servlet 3多部分文件上传项目

Published At
Categories with 技术
Tagged with
comments powered by Disqus