servletcontext.getRealPath("/") 的意思是获取当前web应用程序的根目录在服务器上的真实路径。什么时候应该使用它呢?

70
在以下代码片段中:
ServletContext context = request.getServletContext();
String path = context.getRealPath("/");

getRealPath() 方法中的 / 代表什么?我应该在什么情况下使用它?


1
这被称为WebApplicationContext。例如,如果您的应用程序名为TestWebApp,则/将给出路径直到TestWebApp - Dhruvenkumar Shah
1
这是您的Web应用程序的根。 - Strelok
4个回答

134

介绍

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/,您应该能够进一步在FileFileInputStream中使用。
请注意,大多数初学者似乎没有看到/意识到您实际上可以将整个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()更好、更可移植的方法。

如果你只需要获取网络资源的InputStream,最好使用ServletContext#getResourceAsStream(),这样可以确保在WAR扩展的方式下仍然有效。因此,如果你想要index.jspInputStream,那么不要这样做:
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应用程序重新部署时保留数据的简单方法

16
我确信@BalusC会回答这个问题,并且回答得非常好。说真的,你很棒。 - Makky
@BalusC 这个会返回什么 ServletConfig#getServletContext().getRealPath(".") - Sriram
@BalusC 如果我的输入和输出文件在WEB-INF目录下,我该如何使用getResourceAsStream或getResourcePaths来引用它们? - te7
@te7пјҡеҸӘйңҖдҪҝз”ЁgetResourceAsStream("/WEB-INF/filename.ext")жҲ–getResourcePaths("/WEB-INF")гҖӮе…ій”®жҳҜиҰҒжҢҮе®ҡд»Ҙ/ејҖеӨҙзҡ„WebеҶ…е®№зӣёеҜ№и·Ҝеҫ„гҖӮ - BalusC
@BalusC 对于getResourceAsStream,这不是作用域问题,而是语法问题。我必须使用getServletContext().getResourceAsStream(path),其中path = "/WEB-INF/inputfile.txt"。但是当方法执行时,在那一行我现在得到了一个空指针异常。有什么想法吗? - te7
显示剩余5条评论

4
一个Web应用程序的上下文路径是包含Web应用程序的WEB-INF目录的目录。它可以被视为Web应用程序的“主页”。通常,在编写Web应用程序时,重要的是要获取文件系统中此目录的实际位置,因为这使您能够执行读取文件或写入文件等操作。
可以通过ServletContext对象的getRealPath()方法获取此位置。可以将该方法传递一个String参数设置为File.separator,以使用操作系统的文件分隔符(UNIX为“/”,Windows为“\”)获取路径。

2

-1

我的方法:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    try {
        String path = request.getRealPath("/WEB-INF/conf.properties");
        Properties p = new Properties();
        p.load(new FileInputStream(path));

        String StringConexion=p.getProperty("StringConexion");
        String User=p.getProperty("User");
        String Password=p.getProperty("Password");
    }
    catch(Exception e){
        String msg = "Excepcion " + e;
    }
}

虽然这段代码片段可能解决了问题,但它并没有解释为什么或者如何回答这个问题。请在你的代码中包含一个解释,因为这真的有助于提高你的帖子质量。记住,你正在为未来的读者回答问题,而那些人可能不知道你的代码建议的原因。 - Devon_C_Miller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接