"什么是servletcontext.getRealPath("/")的作用,什么时候应该使用它?"
"什么是servletcontext.getRealPath("/")的作用,什么时候应该使用它?"
在以下代码段中:
ServletContext context = request.getServletContext(); String path = context.getRealPath("/");
方法getRealPath()
中的/
代表什么?什么时候应该使用它?
介绍
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"); // Right!
不要将文件写入其中
此外,请注意,即使您可以使用FileOutputStream
向其中写入新文件,但无论何时重新部署WAR文件(例如,添加新文件或编辑文件),所有更改(例如,新文件或编辑文件)都将丢失,原因很简单,所有这些更改都不包含在原始WAR文件中。因此,所有试图在其中保存上传文件的初学者都是错误的。
此外,当服务器未配置为将WAR文件扩展为磁盘文件系统(而是扩展为例如在内存中作为虚拟文件系统时),getRealPath()
将始终返回null
或完全意外的路径。
getRealPath()
是不可移植的;最好永远不要使用它
小心使用getRealPath()
。实际上没有明智的实际应用场景。基于我20年的Java EE经验,总是有另一种比getRealPath()
更好且更可移植的方式。
如果您实际上只需要获取Web资源的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()
。
SetresourcePaths = servletContext.getResourcePaths("/");
您可以通过 ServletContext#getResource()
方法以URL
的形式获得单个资源。当资源不存在时,它将返回null
。
URL resource = servletContext.getResource(path);
或者,如果您打算保存上传的文件或创建临时文件,请参见下面的“另请参阅”链接。