Przeczytałem tutaj, że i tak nie należy zapisywać pliku na serwerze, gdyż nie jest on przenośny, transakcyjny i wymaga parametrów zewnętrznych. Biorąc jednak pod uwagę, że potrzebuję rozwiązania tmp dla tomcat (7) i mam (względną) kontrolę nad maszyną serwera, o której chcę wiedzieć:
Jakie jest najlepsze miejsce do zapisania pliku? Powinienem go zapisać w
/WEB-INF/uploads
(odradzane tutaj ) lub gdzieś pod$CATALINA_BASE
(patrz tutaj ) czy ...? Samouczek JavaEE 6 pobiera ścieżkę od użytkownika (: wtf :). Uwaga: plik nie powinien być w żaden sposób możliwy do pobrania.Czy powinienem ustawić parametr konfiguracyjny zgodnie z opisem tutaj ? Byłbym wdzięczny za trochę kodu (wolałbym podać mu ścieżkę względną - więc jest to przynajmniej Tomcat przenośny) -
Part.write()
wygląda obiecująco - ale najwyraźniej potrzebuje bezwzględnej ścieżkiByłbym zainteresowany prezentacją wad tego podejścia w porównaniu z bazą danych / repozytorium JCR
Niestety FileServlet od @BalusC koncentruje się na pobieraniu plików, podczas gdy jego odpowiedź na temat przesyłania plików pomija część dotyczącą miejsca zapisania pliku.
Preferowane byłoby rozwiązanie, które można łatwo przekształcić w implementację DB lub JCR (np. Jackrabbit ).
źródło
Odpowiedzi:
Przechowuj go w dowolnym miejscu w dostępnej lokalizacji, z wyjątkiem folderu projektu IDE, czyli folderu wdrażania serwera, z powodów wymienionych w odpowiedzi na Przesłany obraz dostępny tylko po odświeżeniu strony :
To naprawdę nie ma znaczenia dla mnie czy kogokolwiek innego, gdzie dokładnie na lokalnym systemie plików na dysku zostanie on zapisany, tak długo, jak nie nie zawsze używać
getRealPath()
metody . Stosowanie tej metody jest w każdym razie niepokojące.Z kolei ścieżkę do miejsca przechowywania można zdefiniować na wiele sposobów. Musisz to wszystko zrobić sam . Być może jest to przyczyną twojego zamieszania, ponieważ w jakiś sposób spodziewałeś się, że serwer zrobi to wszystko automagicznie. Należy pamiętać, że
@MultipartConfig(location)
nie nie określenie miejsca docelowego wysyłania, ale tymczasowe miejsce składowania dla rozmiaru pliku przypadek przekracza próg przechowywania pamięci.Tak więc ścieżkę do ostatecznego miejsca przechowywania można zdefiniować na jeden z następujących sposobów:
Mocno zakodowane:
Zmienna środowiskowa za pośrednictwem
SET UPLOAD_LOCATION=/path/to/uploads
:Argument maszyny wirtualnej podczas uruchamiania serwera za pośrednictwem
-Dupload.location="/path/to/uploads"
:*.properties
wpis pliku jakoupload.location=/path/to/uploads
:web.xml
<context-param>
z nazwąupload.location
i wartością/path/to/uploads
:Jeśli istnieje, użyj lokalizacji udostępnionej przez serwer, np. W JBoss AS / WildFly :
Tak czy inaczej, możesz łatwo odwołać się do pliku i zapisać go w następujący sposób:
Lub, gdy chcesz automatycznie wygenerować unikalną nazwę pliku, aby uniemożliwić użytkownikom nadpisywanie istniejących plików przypadkowo o tej samej nazwie:
Jak uzyskać
part
w JSP / Servlet znajduje się w artykule Jak przesłać pliki na serwer za pomocą JSP / Servlet? a odpowiedź na temat sposobu uzyskaniapart
w JSF znajduje się w artykule Jak przesłać plik za pomocą JSF 2.2 <h: inputFile>? Gdzie jest zapisany plik?Uwaga: nie używaj,
Part#write()
ponieważ interpretuje ścieżkę względem tymczasowego miejsca przechowywania zdefiniowanego w@MultipartConfig(location)
.Zobacz też:
źródło
@MultipartConfig(location)
Określa tymczasowa lokalizacja storge które serwer powinien użyć, gdy rozmiar pliku przekroczy próg pamięcią, a nie stałe miejsce przechowywania, w którym bym ostatecznie jak to mają być przechowywane. Ta wartość jest domyślną ścieżką określoną przezjava.io.tmpdir
właściwość systemową. Zobacz także tę powiązaną odpowiedź na nieudaną próbę JSF: stackoverflow.com/questions/18478154/ ...Part.write
>> Pozwala to konkretnej implementacji na użycie, na przykład, zmiany nazwy pliku, jeśli to możliwe, zamiast kopiowania wszystkich bazowych danych, uzyskując w ten sposób znaczną poprawę wydajności w połączeniu z niektórymi nieznana metoda "wycinania" (w porównaniu z kopiowaniem) z, powiedzmy, pewna biblioteka apache zaoszczędziłaby mi kłopotów z samodzielnym pisaniem bajtów - i odtwarzaniem pliku już tam (zobacz także tutaj )Part#write()
. Zaktualizowałem to odpowiedź."jboss.server.data.dir"
?Publikuję swój ostateczny sposób zrobienia tego na podstawie zaakceptowanej odpowiedzi:
gdzie :
i /WEB-INF/app.properties:
HTH i jeśli znajdziesz błąd, daj mi znać
źródło