Widziałem kilka sugestii, takich jak posiadanie katalogu obrazu jako symbolicznego łącza wskazującego na katalog poza kontenerem WWW, ale czy to podejście będzie działać zarówno w środowisku Windows, jak i * nix?
Jeśli przestrzegasz zasad ścieżki systemu plików * nix (tj. Używasz wyłącznie ukośników w przód /path/to/files), to będzie działać również w systemie Windows bez potrzeby majstrowania przy brzydkich File.separatorkonkatenacjach ciągów. Byłoby to jednak skanowane tylko na tym samym dysku roboczym, z którego zostało wywołane to polecenie. Więc jeśli na przykład Tomcat jest zainstalowane na C:czym /path/to/filesfaktycznie wskazywać C:\path\to\files.
Jeśli wszystkie pliki znajdują się poza aplikacją internetową i chcesz, aby Tomcat DefaultServletje obsługiwał, to w zasadzie wszystko, co musisz zrobić w Tomcat, to dodać następujący element Context do znacznika /conf/server.xmlwewnętrznego <Host>:
<Context docBase="/path/to/files" path="/files" />
W ten sposób będą dostępne przez http://example.com/files/.... W przypadku serwerów opartych na Tomcat, takich jak JBoss EAP 6.x lub starsze, podejście jest zasadniczo takie samo, zobacz także tutaj . Przykład konfiguracji GlassFish / Payara można znaleźć tutaj, a przykład konfiguracji WildFly można znaleźć tutaj .
Jeśli chcesz mieć kontrolę nad odczytu / zapisu plików siebie, to trzeba stworzyć Servletdo tego, który w zasadzie tylko pobiera InputStreamz pliku w smaku na przykład FileInputStreami zapisuje go do OutputStreamz HttpServletResponse.
W odpowiedzi należy ustawić Content-Typenagłówek, aby klient wiedział, którą aplikację skojarzyć z podanym plikiem. I powinieneś ustawić Content-Lengthnagłówek tak, aby klient mógł obliczyć postęp pobierania, w przeciwnym razie będzie nieznany. I powinieneś ustawić Content-Dispositionnagłówek na, attachmentjeśli chcesz okno dialogowe Zapisz jako , w przeciwnym razie klient spróbuje wyświetlić je w tekście. Na koniec po prostu zapisz zawartość pliku w strumieniu wyjściowym odpowiedzi.
Oto podstawowy przykład takiego serwletu:
@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());
}
}
Po zmapowaniu na url-patternprzykład /files/*, możesz to wywołać http://example.com/files/image.png. W ten sposób możesz mieć większą kontrolę nad żądaniami niż te DefaultServlet, na przykład dostarczając domyślny obraz (tj. if (!file.exists()) file = new File("/path/to/files", "404.gif")Lub coś podobnego ). Korzystając również request.getPathInfo()jest korzystne przede request.getParameter()ponieważ jest bardziej przyjazny SEO i inaczej IE nie odbierze poprawną nazwę pliku podczas Save As .
Możesz ponownie użyć tej samej logiki do udostępniania plików z bazy danych. Po prostu wymień new FileInputStream()na ResultSet#getInputStream().
Mam nadzieję że to pomoże.
Zobacz też: