Servlet Upload File und Download File ist eine übliche Aufgabe in einer Java-Webanwendung. Da ich in letzter Zeit viel über Java Servlet geschrieben habe, dachte ich, ein Beispiel dafür zu geben, wie man eine Datei von Servlet zum Server hochlädt und dann vom Server zum Client herunterlädt.
Servlet Upload File
Unser Anwendungsfall besteht darin, eine einfache HTML-Seite bereitzustellen, auf der der Client eine lokale Datei auswählen kann, die auf den Server hochgeladen werden soll. Bei der Anforderung zum Hochladen der Datei wird unser Servlet-Programm die Datei in ein Verzeichnis auf dem Server hochladen und dann die URL bereitstellen, über die der Benutzer die Datei herunterladen kann. Aus Sicherheitsgründen wird dem Benutzer keine direkte URL zum Herunterladen der Datei zur Verfügung gestellt, sondern er erhält einen Link zum Herunterladen der Datei und unser Servlet verarbeitet die Anforderung und sendet die Datei an den Benutzer. Wir erstellen ein dynamisches Webprojekt in Eclipse und die Projektstruktur sieht aus wie das untenstehende Bild. Schauen wir uns alle Komponenten unserer Webanwendung an und verstehen die Implementierung.
HTML-Seite zum Hochladen von Dateien auf den Server mit Java
Wir können eine Datei auf den Server hochladen, indem wir eine POST-Anfrage an das Servlet senden und das Formular übermitteln. Wir können die GET-Methode nicht zum Hochladen von Dateien verwenden. Ein weiterer Punkt, der zu beachten ist, ist, dass das enctype des Formulars multipart/form-data sein sollte. Um eine Datei aus dem Dateisystem des Benutzers auszuwählen, müssen wir das input-Element mit dem type als file verwenden. Daher können wir eine einfache HTML-Seite namens index.html haben, um Dateien hochzuladen:
<html>
<head></head>
<body>
<form action="UploadDownloadFileServlet" method="post" enctype="multipart/form-data">
Select File to Upload:<input type="file" name="fileName">
<br>
<input type="submit" value="Upload">
</form>
</body>
</html>
Serverdateispeicherort für Dateiupload
Wir müssen die Datei in einem Verzeichnis auf dem Server speichern. Wir können dieses Verzeichnis im Programm fest codieren, aber für eine bessere Flexibilität werden wir es in den Bereitstellungsdeskriptor-Kontextparametern konfigurierbar halten. Außerdem fügen wir unsere Upload-Datei-HTML-Seite der Willkommensdateiliste hinzu. Unsere web.xml-Datei wird wie folgt aussehen:
<?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>ServletFileUploadDownloadExample</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<context-param>
<param-name>tempfile.dir</param-name>
<param-value>tmpfiles</param-value>
</context-param>
</web-app>
ServletContextListener für den Dateispeicherort des Dateiuploads
Da wir den Kontextparameter für den Dateispeicherort lesen und ein `File`-Objekt erstellen müssen, können wir einen `ServletContextListener` schreiben, um dies bei der Initialisierung des Kontexts zu erledigen. Wir können den absoluten Verzeichnisstandort und das `File`-Objekt als Kontextattribut festlegen, um von anderen Servlets verwendet zu werden. Unser Implementierungscode für den `ServletContextListener` sieht wie folgt aus.
package com.journaldev.servlet;
import java.io.File;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class FileLocationContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
String rootPath = System.getProperty("catalina.home");
ServletContext ctx = servletContextEvent.getServletContext();
String relativePath = ctx.getInitParameter("tempfile.dir");
File file = new File(rootPath + File.separator + relativePath);
if(!file.exists()) file.mkdirs();
System.out.println("File Directory created to be used for storing files");
ctx.setAttribute("FILES_DIR_FILE", file);
ctx.setAttribute("FILES_DIR", rootPath + File.separator + relativePath);
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
// bei Bedarf bereinigen
}
}
Datei-Upload-Download-Servlet
Aktualisierung: Servlet Specs 3 haben Unterstützung zum Hochladen von Dateien auf den Server in der API hinzugefügt, daher benötigen wir keine Drittanbieter-API. Bitte schauen Sie sich Servlet 3 Datei hochladen an. Für den Dateiupload verwenden wir das Hilfsprogramm Apache Commons FileUpload, für unser Projekt verwenden wir Version 1.3. FileUpload hängt von Apache Commons IO Jar ab, daher müssen wir beide im lib-Verzeichnis des Projekts platzieren, wie Sie es im obigen Bild für die Projektstruktur sehen können. Wir verwenden die DiskFileItemFactory-Fabrik, die eine Methode zum Analysieren des HttpServletRequest-Objekts bereitstellt und eine Liste von FileItem zurückgibt. FileItem bietet nützliche Methoden, um den Dateinamen, Feldnamen im Formular, Größe und Details zum Dateityp der hochzuladenden Datei abzurufen. Um eine Datei in ein Verzeichnis zu schreiben, müssen wir lediglich ein File-Objekt erstellen und es als Argument an die write()-Methode von FileItem übergeben. Da der gesamte Zweck des Servlets darin besteht, eine Datei hochzuladen, werden wir die init() Methode überschreiben, um die DiskFileItemFactory
-Objektinstanz des Servlets zu initialisieren. Wir verwenden dieses Objekt in der Implementierung der doPost()-Methode, um die Datei in das Serververzeichnis hochzuladen. Nachdem die Datei erfolgreich hochgeladen wurde, senden wir dem Client eine Antwort mit der URL zum Herunterladen der Datei. Da HTML-Links die GET-Methode verwenden, fügen wir den Parameter für den Dateinamen in die URL ein und können dieselbe Servlet doGet()-Methode nutzen, um den Dateidownloadprozess zu implementieren. Zur Implementierung des Download-Datei-Servlets öffnen wir zuerst den InputStream für die Datei und verwenden die Methode ServletContext.getMimeType(), um den MIME-Typ der Datei abzurufen, und setzen ihn als Antwortinhaltstyp. Außerdem müssen wir die Länge des Antwortinhalts als Länge der Datei festlegen. Damit der Client versteht, dass wir die Datei als Antwort senden, müssen wir den Header „Content-Disposition“ mit dem Wert „attachment; filename=“Dateiname” setzen. Nachdem wir die Antwortkonfiguration festgelegt haben, können wir den Dateiinhalt aus dem InputStream lesen, ihn in den ServletOutputStream schreiben und dann die Ausgabe an den Client senden. Unsere endgültige Implementierung des UploadDownloadFileServlet-Servlets sieht wie folgt aus.
package com.journaldev.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@WebServlet("/UploadDownloadFileServlet")
public class UploadDownloadFileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private ServletFileUpload uploader = null;
@Override
public void init() throws ServletException{
DiskFileItemFactory fileFactory = new DiskFileItemFactory();
File filesDir = (File) getServletContext().getAttribute("FILES_DIR_FILE");
fileFactory.setRepository(filesDir);
this.uploader = new ServletFileUpload(fileFactory);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = request.getParameter("fileName");
if(fileName == null || fileName.equals("")){
throw new ServletException("File Name can't be null or empty");
}
File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileName);
if(!file.exists()){
throw new ServletException("File doesn't exists on server.");
}
System.out.println("File location on server::"+file.getAbsolutePath());
ServletContext ctx = getServletContext();
InputStream fis = new FileInputStream(file);
String mimeType = ctx.getMimeType(file.getAbsolutePath());
response.setContentType(mimeType != null? mimeType:"application/octet-stream");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
ServletOutputStream os = response.getOutputStream();
byte[] bufferData = new byte[1024];
int read=0;
while((read = fis.read(bufferData))!= -1){
os.write(bufferData, 0, read);
}
os.flush();
os.close();
fis.close();
System.out.println("File downloaded at client successfully");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(!ServletFileUpload.isMultipartContent(request)){
throw new ServletException("Content type is not multipart/form-data");
}
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.write("<html><head></head><body>");
try {
List<FileItem> fileItemsList = uploader.parseRequest(request);
Iterator<FileItem> fileItemsIterator = fileItemsList.iterator();
while(fileItemsIterator.hasNext()){
FileItem fileItem = fileItemsIterator.next();
System.out.println("FieldName="+fileItem.getFieldName());
System.out.println("FileName="+fileItem.getName());
System.out.println("ContentType="+fileItem.getContentType());
System.out.println("Size in bytes="+fileItem.getSize());
File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileItem.getName());
System.out.println("Absolute Path at server="+file.getAbsolutePath());
fileItem.write(file);
out.write("File "+fileItem.getName()+ " uploaded successfully.");
out.write("<br>");
out.write("<a href=\"UploadDownloadFileServlet?fileName="+fileItem.getName()+"\">Download "+fileItem.getName()+"</a>");
}
} catch (FileUploadException e) {
out.write("Exception in uploading file.");
} catch (Exception e) {
out.write("Exception in uploading file.");
}
out.write("</body></html>");
}
}
Die Beispiel-Ausführung des Projekts ist auf den folgenden Bildern zu sehen.
Servlet-Datei-Upload-Download-Projekt herunterladen
Sie können die Apache Commons IO Jar und Apache Commons FileUpload Jar von den folgenden URLs herunterladen. https://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi https://commons.apache.org/proper/commons-io/download_io.cgi
Servlet-Datei-Upload-Download Beispielprojekt herunterladen
Sehen Sie sich den nächsten Artikel in der Serie über Servlet-Ausnahmebehandlung an.
Source:
https://www.digitalocean.com/community/tutorials/servlet-upload-file-download-example