Ответ 1
Введение
ServletContext#getRealPath()
предназначен для преобразования пути к веб-контенту (путь в расширенной структуре папок WAR в файловой системе диска сервера) в абсолютный путь к файловой системе диска.
"/"
представляет корень веб-контента. То есть он представляет папку web
, как в приведенной ниже структуре проекта:
YourWebProject
|-- src
| :
|
|-- web
| |-- META-INF
| | '-- MANIFEST.MF
| |-- WEB-INF
| | '-- web.xml
| |-- index.jsp
| '-- login.jsp
:
Таким образом, передача "/"
в getRealPath()
вернет вам абсолютный путь к файловой системе диска в папке /web
расширенного файла WAR проекта. Нечто подобное /path/to/server/work/folder/some.war/
, которое вы сможете использовать в File
или FileInputStream
.
Обратите внимание, что большинство новичков, похоже, не видят/не понимают, что на самом деле вы можете передать ему полный путь к веб-контенту и что они часто используют
String absolutePathToIndexJSP = servletContext.getRealPath("/") + "index.jsp"; // Wrong!
или даже
String absolutePathToIndexJSP = servletContext.getRealPath("") + "index.jsp"; // Wronger!
вместо
String absolutePathToIndexJSP = servletContext.getRealPath("/index.jsp"); // Right!
Никогда не пишите туда файлы
Также обратите внимание, что даже если вы можете записать в него новые файлы, используя FileOutputStream
, все изменения (например, новые файлы или отредактированные файлы) будут теряться при каждом повторном развертывании WAR; по той простой причине, что все эти изменения не содержатся в исходном файле WAR. Так что все начинающие, которые пытаются сохранить загруженные файлы, делают это неправильно.
Более того, getRealPath()
всегда будет возвращать null
или совершенно неожиданный путь, когда сервер не настроен для расширения файла WAR в файловую систему диска, а вместо этого, например, в. память как виртуальная файловая система.
getRealPath()
не переносим; вам лучше никогда не использовать его
Используйте getRealPath()
осторожно. На самом деле для этого нет никаких реальных вариантов использования. Основываясь на моем 20-летнем опыте работы с Java EE, всегда был другой способ, который намного лучше и более переносим, чем getRealPath()
.
Если все, что вам действительно нужно, это получить InputStream
веб-ресурса, лучше используйте ServletContext#getResourceAsStream()
вместо этого, это будет работать независимо от способа расширения WAR. Итак, если вы, например, хотите InputStream
из index.jsp
, то не делайте:
InputStream input = new FileInputStream(servletContext.getRealPath("/index.jsp")); // Wrong!
Но вместо этого сделайте:
InputStream input = servletContext.getResourceAsStream("/index.jsp"); // Right!
Или, если вы хотите получить список всех доступных путей к веб-ресурсам, используйте ServletContext#getResourcePaths()
.
Set<String> resourcePaths = servletContext.getResourcePaths("/");
Вы можете получить отдельный ресурс как URL
через ServletContext#getResource()
. Это вернет null
, когда ресурс не существует.
URL resource = servletContext.getResource(path);
Или, если вы намереваетесь сохранить загруженный файл или создать временный файл, см. ссылки ниже "См. также".