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.separator
konkatenacjach 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/files
faktycznie wskazywać C:\path\to\files
.
Jeśli wszystkie pliki znajdują się poza aplikacją internetową i chcesz, aby Tomcat DefaultServlet
je obsługiwał, to w zasadzie wszystko, co musisz zrobić w Tomcat, to dodać następujący element Context do znacznika /conf/server.xml
wewnę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ć Servlet
do tego, który w zasadzie tylko pobiera InputStream
z pliku w smaku na przykład FileInputStream
i zapisuje go do OutputStream
z HttpServletResponse
.
W odpowiedzi należy ustawić Content-Type
nagłówek, aby klient wiedział, którą aplikację skojarzyć z podanym plikiem. I powinieneś ustawić Content-Length
nagłówek tak, aby klient mógł obliczyć postęp pobierania, w przeciwnym razie będzie nieznany. I powinieneś ustawić Content-Disposition
nagłówek na, attachment
jeś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-pattern
przykł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ż:
<Context docBase="/path/to/images" path="/images" />
w systemie Windows, ale otrzymuję ścieżkę względem folderu webapps:C:\install\apache-tomcat-8.0.26\webapps\tmp] is not valid
<Context docBase="C:\tmp\" path="/images" />
HTTP Status 404 - /images/
podczas robieniahttp://localhost:8080/images/
:, ALE konkretny plik ztmp
pracy:http://localhost:8080/images/Tulips.jpg
jest OKMożesz to zrobić, umieszczając swoje obrazy na stałej ścieżce (na przykład: / var / images lub c: \ images), dodaj ustawienie w ustawieniach aplikacji (reprezentowane w moim przykładzie przez Settings.class) i załaduj je w ten sposób w swoim
HttpServlet
:String filename = Settings.getValue("images.path") + request.getParameter("imageName") FileInputStream fis = new FileInputStream(filename); int b = 0; while ((b = fis.read()) != -1) { response.getOutputStream().write(b); }
Lub jeśli chcesz manipulować obrazem:
String filename = Settings.getValue("images.path") + request.getParameter("imageName") File imageFile = new File(filename); BufferedImage image = ImageIO.read(imageFile); ImageIO.write(image, "image/png", response.getOutputStream());
wtedy kod html byłby
<img src="imageServlet?imageName=myimage.png" />
Oczywiście powinieneś pomyśleć o udostępnianiu różnych typów treści - „obraz / jpeg”, na przykład na podstawie rozszerzenia pliku. Powinieneś także zapewnić trochę buforowania.
Ponadto możesz użyć tego serwletu do przeskalowania jakości obrazów, podając parametry szerokości i wysokości jako argumenty i używając
image.getScaledInstance(w, h, Image.SCALE_SMOOTH
), oczywiście biorąc pod uwagę wydajność.źródło
Dodaj do server.xml:
<Context docBase="c:/dirtoshare" path="/dir" />
Włącz parametr listy plików dir w web.xml:
<init-param> <param-name>listings</param-name> <param-value>true</param-value> </init-param>
źródło
Warunek: dostęp do statycznych zasobów (obrazów / filmów itp.) Spoza katalogu WEBROOT lub z dysku lokalnego
Krok 1:
Utwórz folder pod aplikacjami internetowymi serwera Tomcat. Powiedzmy, że nazwa folderu to myproj
Krok 2:
W myproj utwórz folder WEB-INF w tym celu utwórz prosty plik web.xml
kod pod web.xml
<web-app> </web-app>
Struktura katalogów dla powyższych dwóch kroków
c:\programfile\apachesoftwarefoundation\tomcat\...\webapps | |---myproj | | | |---WEB-INF | | |---web.xml
Krok 3:
Teraz utwórz plik xml o nazwie myproj.xml w następującej lokalizacji
c:\programfile\apachesoftwarefoundation\tomcat\conf\catalina\localhost
KOD w myproj.xml:
<Context path="/myproj/images" docBase="e:/myproj/" crossContext="false" debug="0" reloadable="true" privileged="true" />
Krok 4:
4 A) Teraz utwórz folder o nazwie myproj na dysku E swojego dysku twardego i utwórz nowy
folder z nazwami obrazów i umieść niektóre obrazy w folderze obrazów
(e:myproj\images\)
Załóżmy, że myfoto.jpg znajduje się pod
e:\myproj\images\myfoto.jpg
4 B) Teraz utwórz folder o nazwie WEB-INF w
e:\myproj\WEB-INF
i utwórz plik web.xml w folderze WEB-INFKod w web.xml
<web-app> </web-app>
Krok 5:
Teraz utwórz dokument .html o nazwie index.html i umieść go pod e: \ myproj
KOD pod index.html Witamy w Myproj
Struktura katalogów dla powyższych kroków 4 i 5 jest następująca
E:\myproj |--index.html | |--images | |----myfoto.jpg | |--WEB-INF | |--web.xml
Krok 6:
Teraz uruchom serwer apache tomcat
Krok 7:
Otwórz przeglądarkę i wpisz adres URL w następujący sposób
http://localhost:8080/myproj
następnie u wyświetl zawartość zawartą w pliku index.html
Krok 8:
aby uzyskać dostęp do obrazów z lokalnego dysku twardego (poza webrootem)
http://localhost:8080/myproj/images/myfoto.jpg
źródło
Oto historia z mojego miejsca pracy:
- Staramy się przesyłać powielone obrazy i pliki dokumentów za pomocą Struts 1 i Tomcat 7.x.
- Staramy się zapisywać przesłane pliki do systemu plików, nazwę pliku i pełną ścieżkę do rekordów bazy danych.
- Próbujemy oddzielić foldery plików poza katalogiem aplikacji internetowych . (*)
Poniższe rozwiązanie jest dość proste, skuteczne w przypadku wymagania (*):
W pliku
META-INF/context.xml
o następującej treści: (Przykład, moja aplikacja działa whttp://localhost:8080/ABC
, moja aplikacja / projekt o nazwieABC
). (jest to również pełna zawartość plikucontext.xml
)<?xml version="1.0" encoding="UTF-8"?> <Context path="/ABC" aliases="/images=D:\images,/docs=D:\docs"/>
(działa z Tomcat w wersji 7 lub nowszej)
Wynik: utworzyliśmy 2 alias. Na przykład zapisujemy obrazy pod adresem:
D:\images\foo.jpg
i wyświetlamy z linku lub za pomocą tagu obrazu:<img src="http://localhost:8080/ABC/images/foo.jsp" alt="Foo" height="142" width="142">
lub
<img src="/images/foo.jsp" alt="Foo" height="142" width="142">
(Używam Netbeans 7.x, Netbeans wydaje się automatycznie tworzyć plik
WEB-INF\context.xml
)źródło
Jeśli zdecydujesz się do wysłania
FileServlet
wówczas konieczne będzie takżeallowLinking="true"
wcontext.xml
w celu umożliwieniaFileServlet
przemierzać dowiązania.Zobacz http://tomcat.apache.org/tomcat-6.0-doc/config/context.html
źródło
jeśli ktoś nie jest w stanie rozwiązać swojego problemu za pomocą zaakceptowanej odpowiedzi, zwróć uwagę na poniższe uwagi:
localhost:<port>
z<img> src
atrybutem.context docBase
samodzielnie tworzy wpis w swoim lokalnymserver.xml
pliku.źródło
Przeczytaj InputStream pliku i zapisz go w
ServletOutputStream
celu wysłania danych binarnych do klienta.@WebServlet("/files/URLStream") public class URLStream extends HttpServlet { private static final long serialVersionUID = 1L; public URLStream() { super(); } protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { File source = new File("D:\\SVN_Commit.PNG"); long start = System.nanoTime(); InputStream image = new FileInputStream(source); /*String fileID = request.getParameter("id"); System.out.println("Requested File ID : "+fileID); // Mongo DB GridFS - https://stackoverflow.com/a/33544285/5081877 image = outputImageFile.getInputStream();*/ if( image != null ) { BufferedInputStream bin = null; BufferedOutputStream bout = null; ServletOutputStream sos = response.getOutputStream(); try { bin = new BufferedInputStream( image ); bout = new BufferedOutputStream( sos ); int ch =0; ; while((ch=bin.read())!=-1) { bout.write(ch); } } finally { bin.close(); image.close(); bout.close(); sos.close(); } } else { PrintWriter writer = response.getWriter(); writer.append("Something went wrong with your request."); System.out.println("Image not available."); } System.out.println("Time taken by Stream Copy = "+(System.nanoTime()-start)); } }
Podaj adres URL bezpośrednio do
src
atrybutu.<img src='http://172.0.0.1:8080/ServletApp/files/URLStream?id=5a575be200c117cc2500003b' alt="mongodb File"/> <img src='http://172.0.0.1:8080/ServletApp/files/URLStream' alt="local file"/> <video controls="controls" src="http://172.0.0.1:8080/ServletApp/files/URLStream"></video>
źródło
Jeśli chcesz pracować z JAX-RS (np. RESTEasy), spróbuj tego:
@Path("/pic") public Response get(@QueryParam("url") final String url) { String picUrl = URLDecoder.decode(url, "UTF-8"); return Response.ok(sendPicAsStream(picUrl)) .header(HttpHeaders.CONTENT_TYPE, "image/jpg") .build(); } private StreamingOutput sendPicAsStream(String picUrl) { return output -> { try (InputStream is = (new URL(picUrl)).openStream()) { ByteStreams.copy(is, output); } }; }
za pomocą
javax.ws.rs.core.Response
icom.google.common.io.ByteStreams
źródło
Zrobiłem to jeszcze prościej. Problem: plik CSS zawiera linki URL do folderu img. Pobiera 404.
Spojrzałem na adres URL, http: // tomcatfolder: port / img / blablah.png , który nie istnieje. Ale to naprawdę wskazuje na aplikację ROOT w Tomcat.
Więc właśnie skopiowałem folder img z mojej aplikacji internetowej do tej aplikacji ROOT. Pracuje!
Oczywiście nie jest to zalecane do produkcji, ale dotyczy to wewnętrznej aplikacji do tworzenia narzędzi.
źródło