简介
ServletContext#getRealPath() 旨在将 Web 内容路径(服务器磁盘文件系统上扩展的 WAR 文件夹结构中的路径)转换为绝对磁盘文件系统路径。
"/" 代表 Web 内容根。 IE。它代表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"); // Right!
永远不要在那里写文件
另外请注意,即使您可以使用FileOutputStream 将新文件写入其中,但只要重新部署 WAR,所有更改(例如新文件或编辑的文件)都将丢失;原因很简单,所有这些更改都不包含在原始 WAR 文件中。所以所有试图在其中保存上传文件的初学者都做错了。
此外,getRealPath() 将始终返回 null 或当服务器未配置为将 WAR 文件扩展为磁盘文件系统时,会返回一个完全意外的路径,而是进入例如内存作为虚拟文件系统。
getRealPath() 不可携带;你最好不要使用它
谨慎使用getRealPath()。实际上 没有 明智的现实世界用例。根据我 20 年的 Java EE 经验,总是有另一种方式比 getRealPath() 更好、更便携。
如果您真正需要的是获取 Web 资源的 InputStream,最好使用 ServletContext#getResourceAsStream(),无论 WAR 的扩展方式如何,这都将起作用。因此,例如,如果您想要 index.jsp 中的 InputStream,那么 not 这样做:
InputStream input = new FileInputStream(servletContext.getRealPath("/index.jsp")); // Wrong!
而是这样做:
InputStream input = servletContext.getResourceAsStream("/index.jsp"); // Right!
或者,如果您打算获取所有可用网络资源路径的列表,请改用ServletContext#getResourcePaths()。
Set<String> resourcePaths = servletContext.getResourcePaths("/");
您可以通过ServletContext#getResource() 获取URL 的单个资源。当资源不存在时,这将返回null。
URL resource = servletContext.getResource(path);
或者,如果您打算保存上传的文件或创建临时文件,请参阅下面的“另请参阅”链接。
另见: