介绍
ServletContext#getRealPath()
旨在将 Web 内容路径(服务器磁盘文件系统上扩展的 WAR 文件夹结构中的路径)转换为绝对磁盘文件系统路径。
"/"
表示 Web 内容根目录。即它代表以下项目结构中的 web
文件夹:
YourWebProject
|-- src
| :
|
|-- web
| |-- META-INF
| | `-- MANIFEST.MF
| |-- WEB-INF
| | `-- web.xml
| |-- index.jsp
| `-- login.jsp
:
所以,将
“/”
传递给
getRealPath()
将返回项目扩展的WAR文件的
/web
文件夹的绝对磁盘文件系统路径。类似于
/path/to/server/work/folder/some.war/
,您应该能够进一步在
File
或
FileInputStream
中使用。
请注意,大多数初学者似乎没有看到/意识到您实际上可以将整个Web内容路径传递给它,并且他们经常使用
String absolutePathToIndexJSP = servletContext.getRealPath("/") + "index.jsp"; // Wrong!
甚至
String absolutePathToIndexJSP = servletContext.getRealPath("") + "index.jsp"; // Wronger!
替代
String absolutePathToIndexJSP = servletContext.getRealPath("/index.jsp")
不要在这里写文件
请注意,即使您可以使用FileOutputStream
将新文件写入其中,所有更改(例如新文件或编辑的文件)都会在重新部署WAR时丢失;原因很简单,所有这些更改都不包含在原始WAR文件中。因此,所有试图在此处保存上传文件的初学者都是错误的。
此外,当服务器未配置为将WAR文件扩展到磁盘文件系统而是扩展到内存作为虚拟文件系统时,getRealPath()
将始终返回null
或完全意外的路径。
getRealPath()
不可移植;最好永远不要使用它
小心使用getRealPath()
。实际上,没有任何合理的真实用例。基于我20年的Java EE经验,总是有比getRealPath()
更好、更可移植的方法。
如果你只需要获取网络资源的
InputStream
,最好使用
ServletContext#getResourceAsStream()
,这样可以确保在WAR扩展的方式下仍然有效。因此,如果你想要
index.jsp
的
InputStream
,那么
不要这样做:
InputStream input = new FileInputStream(servletContext.getRealPath("/index.jsp")); // Wrong!
但是,相反要这样做:
InputStream input = servletContext.getResourceAsStream("/index.jsp"); // Right!
如果您想获取所有可用的Web资源路径列表,请使用
ServletContext#getResourcePaths()
。
Set<String> resourcePaths = servletContext.getResourcePaths("/")
您可以通过
ServletContext#getResource()
获取一个单独的资源作为
URL
。当资源不存在时,它将返回
null
。
URL resource = servletContext.getResource(path)
如果你打算保存已上传的文件或创建临时文件,请参考下面的“另请参阅”链接。
另请参阅:
-
getResourceAsStream()与FileInputStream的比较
-
在Servlet应用程序中保存上传文件的推荐方法
-
在Java EE 7 Web应用程序重新部署时保留数据的简单方法
WebApplicationContext
。例如,如果您的应用程序名为TestWebApp
,则/
将给出路径直到TestWebApp
。 - Dhruvenkumar Shah