Frage

Ich habe eine Java EE Web-Anwendung entwickelt. Diese Anwendung ermöglicht es ein Benutzer eine Datei mit Hilfe eines Browsers zu laden. Sobald der Benutzer seine Datei hochgeladen hat, diese Anwendung speichert zuerst die hochgeladene Datei auf dem Server (auf dem es ausgeführt wird), und verarbeitet sie.

Zur Zeit bin ich Speichern der Datei auf dem Server wie folgt:

try {
    // formFile represents the uploaded file
    FormFile formFile = programForm.getTheFile();
    String path = getServlet().getServletContext().getRealPath("") + "/"
        + formFile.getFileName();
    System.out.println(path);
    file = new File(path);
    outputStream = new FileOutputStream(file);
    outputStream.write(formFile.getFileData());
}

, wo der formFile repräsentiert die hochgeladene Datei.

Nun, das Problem ist, dass es in Ordnung auf einigen Servern läuft, aber auf einigen Servern die getServlet().getServletContext().getRealPath("") zurückkehrt null so den letzten Weg, den ich erhalte ist null/filename und die Datei speichern, nicht auf dem Server.

Wenn diese Option aktiviert ich die API ServletContext.getRealPath() Methode, fand ich folgendes:

  

public java.lang.String getRealPath(java.lang.String path)

     

Gibt einen String den echten Pfad für einen bestimmten virtuellen Pfad enthält. Beispielsweise gibt der Pfad "/index.html" der absolute Dateipfad auf dem Dateisystem des Servers würde durch eine Anfrage für "http://host/contextPath/index.html" serviert werden, wo contextPath des Kontextpfad dieser ServletContext ist.

     

Der wirkliche Pfad wird in einer geeigneten Form an den Computer und das Betriebssystem zurückgegeben, auf das die Servlet-Container ausgeführt wird, einschließlich den richtigen Pfad Separatoren. Diese Methode gibt null, wenn die Servlet-Container den virtuellen Pfad zu einem echten Weg aus irgendeinem Grunde nicht übersetzen können (zB wenn der Inhalt von einem .war-Archiv zur Verfügung gestellt wird).

So, Gibt es eine andere Art und Weise, durch die ich Dateien auf den Servern speichern können auch die null für getServlet().getServletContext().getRealPath("") zurückkehrt

War es hilfreich?

Lösung

Das Schreiben in das Dateisystem aus einem Behälter Java EE ist nicht wirklich zu empfehlen, vor allem wenn man die geschriebenen Daten verarbeiten muß:

  • es ist nicht transaktions
  • es schadet die Portabilität (was ist, wenn Sie in einer Cluster-Umgebung)
  • erfordert die Einrichtung externer Parameter für die Zielposition

Wenn dies eine Option ist, würde ich die Dateien in der Datenbank speichern oder eine JCR-Repository verwenden (wie Hasen ).

Andere Tipps

Mit dem spec, die einzige „echte“ Pfad Sie garantiert einen Servlet-Container erhalten zu bilden, ist ein temporäres Verzeichnis.

Sie können über die ServletContext.gerAttribute("javax.servlet.context.tempdir") bekommen, dass. Allerdings sind diese Dateien auf den Web-Kontext nicht sichtbar sind (das heißt man kann nicht eine einfache URL veröffentlichen, um diese Dateien zu liefern), und die Dateien werden in keiner Weise garantiert eine Web-App oder Neustart des Servers, um zu überleben.

Wenn Sie einfach einen Platz benötigen, eine Arbeitsdatei für eine kurze Zeit zu speichern, dann dies funktioniert gut für Sie.

Wenn Sie wirklich ein Verzeichnis benötigen, können Sie es ein Konfigurationsparameter (entweder eine Umgebungsvariable, eine Java-Eigenschaft (dh java -Dyour.file.here=/tmp/files ...), einen Kontextparametersatz in der web.xml, einen Konfigurationsparameter in Ihrer Datenbank über eine gespeicherte Web-Formular, etc.). Dann ist es an der deployer bis dieses Verzeichnis für Sie einrichten.

Wenn Sie jedoch müssen später tatsächlich die Datei dienen, werden Sie entweder benötigen einen Container spezifischen Mechanismus zu „montieren“ externe Verzeichnisse in Ihrem Web-App (Glassfish als „alternative doc roots“, andere haben ähnliche Konzepte), oder Sie benötigen ein Servlet / Filter zu schreiben, Dateispeicher außerhalb Ihres Web-App zu servieren. Diese FileServlet ist ganz vollständig, und wie Sie können sehen, die Erstellung Ihrer eigenen, wenn auch nicht schwer, nicht trivial ist es richtig zu machen.

Edit:

Der grundlegende Kern ist die gleiche, aber anstatt mit „getRealPath“, verwenden Sie einfach „getInitParameter“.

So:

String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;

Und auf dem Weg sein.

Bearbeiten wieder:

Was den Inhalt des Wegs, würde ich ihm einen absoluten Pfad geben. Andernfalls müßten Sie wissen, wo der App-Server seinen Standardpfad während exeuction setzt, und jeder App-Server auch verschiedene Verzeichnisse verwenden. Zum Beispiel, ich glaube, das Arbeitsverzeichnis für das Glassfish Konfigurationsverzeichnis des laufenden Domäne ist. Keine besonders offensichtliche Wahl.

So verwenden Sie einen absoluten Pfad, auf jeden Fall. Auf diese Weise wissen Sie, wo die Dateien gehen, und Sie können für dieses Verzeichnis der Zugriffsrechte auf OS-Ebene steuern, wenn das notwendig ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top