Servlet 3 Datei-Upload – @MultipartConfig, Teil

Heute werden wir uns ein Servlet 3-Beispiel für den Datei-Upload ansehen, das die @MultipartConfig-Annotation und javax.servlet.http.Part verwendet. Vor einiger Zeit habe ich einen Artikel über den Servlet-Datei-Upload geschrieben und die Apache FileUpload-API verwendet, aber hier werden wir das Servlet 3-Datei-Upload-Feature verwenden.

Servlet 3-Datei-Upload

Da Datei-Upload eine häufige Aufgabe in Webanwendungen ist, hat die Servlet-Spezifikation 3.0 zusätzliche Unterstützung zum Hochladen von Dateien auf den Server bereitgestellt, und wir müssen nicht von APIs von Drittanbietern abhängig sein. In diesem Tutorial werden wir sehen, wie wir die Servlet 3.0-API zum Hochladen von Dateien auf den Server verwenden können.

MultipartConfig

Wir müssen den Datei-Upload-Handler-Servlet mit der MultipartConfig-Annotation annotieren, um multipart/form-data-Anfragen zu verarbeiten, die zum Hochladen von Dateien auf den Server verwendet werden. Die MultipartConfig-Annotation hat folgende Attribute:

  • fileSizeThreshold: Wir können die Größenschwelle angeben, nach der die Datei auf die Festplatte geschrieben wird. Der Größenwert ist in Byte, also sind 1024*1024*10 10 MB.
  • Standort: Verzeichnis, in dem Dateien standardmäßig gespeichert werden. Der Standardwert ist „“.
  • maxFileSize: Maximale Größe, die zum Hochladen einer Datei erlaubt ist, wird in Bytes angegeben. Der Standardwert ist -1L, was unbegrenzt bedeutet.
  • maxRequestSize: Maximale Größe, die für einen multipart/form-data-Anforderung erlaubt ist. Der Standardwert ist -1L, was unbegrenzt bedeutet.

Erfahren Sie mehr über Annotationen unter Java-Annotations-Tutorial.

Part-Schnittstelle

Die Part-Schnittstelle stellt ein Teil oder ein Formularfeld dar, das innerhalb einer multipart/form-data-POST-Anforderung empfangen wurde. Einige wichtige Methoden sind getInputStream() und write(String fileName), die wir zum Lesen und Schreiben von Dateien verwenden können.

Änderungen an HttpServletRequest

Neue Methoden wurden in HttpServletRequest hinzugefügt, um alle Teile in einer multipart/form-data-Anfrage über die Methode getParts() zu erhalten. Wir können einen bestimmten Teil mit der Methode getPart(String partName) erhalten. Lassen Sie uns ein einfaches Projekt betrachten, in dem wir die obigen API-Methoden verwenden, um eine Datei mithilfe eines Servlets hochzuladen. Unsere Projektstruktur wird wie auf dem folgenden Bild aussehen.

HTML-Formular

Wir haben eine einfache HTML-Seite, auf der wir die Datei zum Hochladen auswählen und die Anfrage an den Server senden können, um sie hochzuladen. 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>

Datei-Upload-Servlet

Hier ist unsere Implementierung des Datei-Upload-Servlets. FileUploadServlet.java

package com.journaldev.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 {
        // erhält den absoluten Pfad der Webanwendung
        String applicationPath = request.getServletContext().getRealPath("");
        // konstruiert den Pfad des Verzeichnisses zum Speichern der hochgeladenen Datei
        String uploadFilePath = applicationPath + File.separator + UPLOAD_DIR;
         
        // erstellt das Speicherverzeichnis, falls es nicht vorhanden ist
        File fileSaveDir = new File(uploadFilePath);
        if (!fileSaveDir.exists()) {
            fileSaveDir.mkdirs();
        }
        System.out.println("Upload File Directory="+fileSaveDir.getAbsolutePath());
        
        String fileName = null;
        //Alle Teile aus der Anfrage erhalten und in die Datei auf dem Server schreiben
        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 "";
    }
}

Beachten Sie die Verwendung der @MultipartConfig-Annotation, um verschiedene Größenparameter für den Upload von Dateien anzugeben. Wir müssen das Anforderungsheader-Attribut „content-disposition“ verwenden, um den vom Client gesendeten Dateinamen zu erhalten. Wir werden die Datei mit demselben Namen speichern. Der Verzeichnisstandort ist relativ zur Webanwendung, in der ich die Datei speichere. Sie können ihn auf einen anderen Ort wie im Apache Commons FileUpload-Beispiel konfigurieren.

Response JSP

A simple JSP page that will be sent as response to client once the file is uploaded successfully to server. 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>

Deployment Descriptor

Es gibt nichts Neues in der web.xml-Datei für den Servlet-Dateiupload, sie wird nur verwendet, um die index.html als Willkommensdatei festzulegen. 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>

Wenn wir die Anwendung ausführen, erhalten wir folgende Seiten als Antwort. Die Protokolle zeigen den Verzeichnisstandort an, an dem die Datei gespeichert ist, und die Informationen im content-disposition-Header.

Upload File Directory=/Users/pankaj/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"

I am running Tomcat through Eclipse, that’s why file location is like this. If you run tomcat through command line and deploy application by exporting as WAR file into webapps directory, you will get different structure but a clear one.

Herunterladen Servlet 3 Mehrteilige Datei-Upload-Projekt

Source:
https://www.digitalocean.com/community/tutorials/servlet-3-file-upload-multipartconfig-part