Ich habe einige Vorschläge gesehen, wie beispielsweise, dass das Bildverzeichnis ein symbolischer Link ist, der auf ein Verzeichnis außerhalb des Webcontainers verweist. Funktioniert dieser Ansatz jedoch sowohl in Windows- als auch in * nix-Umgebungen?
Wenn Sie die Pfadregeln für das * nix-Dateisystem einhalten (dh Sie verwenden ausschließlich Schrägstriche wie in /path/to/files
), funktioniert dies auch unter Windows, ohne dass Sie mit hässlichen File.separator
Zeichenfolgenverkettungen herumspielen müssen. Es wird jedoch nur auf derselben Arbeitsplatte gescannt, von der aus dieser Befehl aufgerufen wird. Wenn also beispielsweise Tomcat installiert C:
ist, /path/to/files
würde das tatsächlich darauf verweisen C:\path\to\files
.
Wenn sich die Dateien alle außerhalb der Webanwendung befinden und Sie möchten, dass Tomcat DefaultServlet
sie verarbeitet, müssen Sie in Tomcat grundsätzlich das folgende Context-Element zum /conf/server.xml
internen <Host>
Tag hinzufügen :
<Context docBase="/path/to/files" path="/files" />
Auf diese Weise sind sie über zugänglich http://example.com/files/...
. Das GlassFish / Payara-Konfigurationsbeispiel finden Sie hier und das WildFly-Konfigurationsbeispiel finden Sie hier .
Wenn Sie die Kontrolle haben wollen , über das Lesen / Schreiben von Dateien selbst, dann müssen Sie ein schaffen Servlet
für diese , die im Grunde nur eine bekommt InputStream
der Datei im Geschmack von beispielsweise FileInputStream
und schreibt sie in die OutputStream
von derHttpServletResponse
.
In der Antwort sollten Sie den Content-Type
Header so festlegen , dass der Client weiß, welche Anwendung mit der bereitgestellten Datei verknüpft werden soll. Außerdem sollten Sie den Content-Length
Header so einstellen , dass der Client den Download-Fortschritt berechnen kann, da er sonst nicht bekannt ist. Und Sie sollten den Content-Disposition
Header auf setzen, attachment
wenn Sie Speichern unter möchten Dialogfeld , da der Client sonst versucht, ihn inline anzuzeigen. Zum Schluss schreiben Sie einfach den Dateiinhalt in den Antwortausgabestream.
Hier ist ein grundlegendes Beispiel für ein solches Servlet:
@WebServlet("/files/*")
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String filename = URLDecoder.decode(request.getPathInfo().substring(1), "UTF-8");
File file = new File("/path/to/files", filename);
response.setHeader("Content-Type", getServletContext().getMimeType(filename));
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
Files.copy(file.toPath(), response.getOutputStream());
}
}
Wenn Sie url-pattern
beispielsweise einem von zugeordnet sind /files/*
, können Sie es von aufrufen http://example.com/files/image.png
. Auf diese Weise können Sie mehr Kontrolle über die Anforderungen haben als über die Anforderungen DefaultServlet
, z. B. die Bereitstellung eines Standardabbilds (dh if (!file.exists()) file = new File("/path/to/files", "404.gif")
oder so). Auch die Verwendung von request.getPathInfo()
wird oben bevorzugt, request.getParameter()
da es SEO-freundlicher ist und der IE sonst beim Speichern unter nicht den richtigen Dateinamen auswählt .
Sie können dieselbe Logik zum Bereitstellen von Dateien aus der Datenbank wiederverwenden. Ersetzen Sie einfach new FileInputStream()
durch ResultSet#getInputStream()
.
Hoffe das hilft.
Siehe auch: