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.separatorZeichenfolgenverkettungen 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/fileswü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 DefaultServletsie verarbeitet, müssen Sie in Tomcat grundsätzlich das folgende Context-Element zum /conf/server.xmlinternen <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 Servletfür diese , die im Grunde nur eine bekommt InputStreamder Datei im Geschmack von beispielsweise FileInputStreamund schreibt sie in die OutputStreamvon derHttpServletResponse .
In der Antwort sollten Sie den Content-TypeHeader so festlegen , dass der Client weiß, welche Anwendung mit der bereitgestellten Datei verknüpft werden soll. Außerdem sollten Sie den Content-LengthHeader so einstellen , dass der Client den Download-Fortschritt berechnen kann, da er sonst nicht bekannt ist. Und Sie sollten den Content-DispositionHeader auf setzen, attachmentwenn 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-patternbeispielsweise 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: