【问题标题】:Why does getRealPath() return null when deployed with a .war file? [duplicate]为什么使用 .war 文件部署时 getRealPath() 返回 null? [复制]
【发布时间】:2009-02-11 10:21:14
【问题描述】:

getRealPath() 返回本地系统中的实际路径,但使用.war 文件部署时返回 null。

<%@ page import="java.io.*" %>
<%@ page contentType="text/html;charset=ISO-8859-1" %> 
<%
int iLf = 10;
char cLf = (char)iLf;
String a= application.getResource("/");
//String myfile = application.getRealPath("/")+ "generate.xml";
//String myfile = request.getContextPath()+"generate.xml";
//String myfile = request.getRealPath("/")+"generate.xml";

out.println(myfile);    
File outputFile = new File(myfile);
outputFile.createNewFile();
FileWriter outfile = new FileWriter(outputFile);
outfile.write(" <?xml version='1.0' encoding='UTF-8'?> "+cLf);
outfile.write(" <playlist version='1' xmlns = 'http://xspf.org/ns/0/' > " +cLf);
outfile.write(" <title>My Band Rocks Your Socks</title> "+cLf); 
outfile.write("<trackList>"+cLf); 
%>
 <%! String[] sports; %>
 <%
    sports = request.getParameterValues("sports");

    out.println("<html><body><h1>hello</h1></body></html>");

    if (sports != null)
    { 
         for (int i = 0; i < sports.length; i++)
         { 
              // outfile.writeln (sports[i]); 
              String total=sports[i];
              String[] sa=total.split("[,]");
              // String[] sub=new String();
              outfile.write("<track>"+cLf);
              for (int j=0;j<sa.length;j++)
              {
                // outfile.writeln(sa[j]);
                // outfile.writeln("sa["+j+"]="+sa[j]);
                if( j == 0)
                {
                     outfile.write("<location>" + sa[0] +"</location>"+cLf); 
                }
                else if (j == 1)
                     {
                        outfile.write("<image>" + sa[1] +"</image>"+cLf); 
                     }
                     else if( j==2)
                          {
                            outfile.write("<title>" + sa[2] +"</title>"+cLf);
                          }

               }// end of inner for loop()       
               outfile.write("</track>"+cLf);
         //outfile.writeln();
      }// end of outer for()
    } 
    //else outfile.writeln ("<b>none<b>");

  outfile.write(" </trackList> "+cLf);
  outfile.write(" </playlist> "+cLf);
  outfile.close();

  %>
<object type="application/x-shockwave-flash" width="400" height="170"
          data="xspf_player.swf?playlist_url=generate.xml">
          <param name="movie" value="xspf_player.swf?playlist_url=generate.xml" />

</object>

谁能为此提供替代方案? 如果你也展示一些示例代码会非常有帮助。

【问题讨论】:

标签: java xml jsp jakarta-ee


【解决方案1】:

首先,ServletRequest.getRealPath(String path) 已弃用。适当的替换是:

ServletContext context = session.getServletContext();
String realContextPath = context.getRealPath(request.getContextPath());

但是,ServletContext.getRealPath(String path) 状态的 API 文档:

“如果 servlet 容器由于任何原因(例如当内容从 .war 存档中可用时)无法将虚拟路径转换为真实路径,则此方法返回 null。”

所以 API 正在履行其合同!但是,一切都不会丢失,因为您可以使用ServletContext 中定义的以下方法从 WAR 加载资源:

ServletContext context = session.getServletContext();
InputStream is = context.getResourceAsStream("generate.xml");

【讨论】:

  • 如果我确实需要路径怎么办?例如在这个问题中:stackoverflow.com/questions/6889728/… 函数 setOutputProperty 需要获取路径的字符串,那我该怎么办?
  • 如果你想写入文件怎么办? getResourceAsStream 返回一个 InputStream 对吧?
  • 'coderanch.com/t/372437/java/java/javax-net-ssl-keyStore-system' 不幸的是,javax.net.ssl.trustStore 属性无法从类路径读取数据,但希望它是文件路径。
  • this.getClass().getResource("/").getPath();
  • @VishnudevK 为我工作。我在/WEB-INF/classes/myKey.pem 有一个密钥文件,并使用this.getClass().getResource("/myKey.pem").getPath() 获得了完整的字符串路径。 IMO,这比使用 ServletContext 和没有 InputStream 更加优雅/直接。只需使用标准的类加载器。
【解决方案2】:

有点晚了,但是当我在 WebLogic 中遇到这个问题时,我遇到了这个问题。我的解决方案是将其添加到我的weblogic.xml:

<?xml version='1.0' encoding='UTF-8'?>
<weblogic-web-app>
    <container-descriptor>
        <show-archived-real-path-enabled>true</show-archived-real-path-enabled>
    </container-descriptor>
</weblogic-web-app>

当您不想(或不能)编辑 WebLogic 服务器上的配置时,我发现此解决方案更好。

【讨论】:

    【解决方案3】:

    你使用 Weblogic 吗?

    如果是 - 那么这是一个 Weblogic 问题,您可以在 Weblogic 管理控制台 ->域->Web 应用程序中修复它 - 单击复选框“已启用存档真实路径”。

    见:http://ananthkannan.blogspot.com/2009/12/servletcontextgetrealpath-returns-null.html

    【讨论】:

      【解决方案4】:

      这也解决了问题:

      weblogic.xml

      <?xml version = '1.0' encoding = 'windows-1252'?>
      <weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd" xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">
      
      <container-descriptor>
        <index-directory-enabled>true</index-directory-enabled>
        <show-archived-real-path-enabled>true</show-archived-real-path-enabled>
      </container-descriptor>
      
      <virtual-directory-mapping>
        <local-path>bla.war</local-path>
        <url-pattern>*</url-pattern>
      </virtual-directory-mapping>
      
      <context-root>bla</context-root>
      

      【讨论】:

        【解决方案5】:

        我不相信有可能做你想做的事。

        您应该使用 getResource 从您的 war 文件中读取 xml 文件(这也可以在没有战争的情况下使用)

        servletContext.getResourceAsStream("/generate.xml")
        

        前导斜杠取决于 generate.xml 的存储位置。

        【讨论】:

        • classloader 和 servletcontext 对于什么是 /generate.xml 可能有不同的想法——一个是通过类路径查看,另一个是通过应用程序上下文(不是从 WEB-INF/classes 计算,而是从WAR 的根)。所以正确的方法是使用ServletContext.getResourceAsStream。
        • 回答问题是主要目标。这个答案没有提供任何有效的解决方案!
        【解决方案6】:

        注意context.getRealPath()在用户权限问题时可以返回null,请检查Web服务器在哪个用户下运行。

        【讨论】:

          【解决方案7】:

          我也有同样的问题。部署到独立服务器时,调用 getRealPath() 返回 null。搜索了一会,我找到了解决方案,它不在代码中。它在您的 Web 服务器的配置中。

          对我来说它是 Weblogic 10.3,你去主页 - - 配置 - Web 应用程序,将 Archived Real Path Enabled 设置为 true。重新启动服务器,一切正常。

          希望这有帮助, 问候。

          【讨论】:

            【解决方案8】:

            如果你想写入

            使用

            this.getClass().getResource("/").getPath();
            

            获取路径

            【讨论】:

            • 谢谢。我花了太多时间寻找这个,哈哈。
            【解决方案9】:

            以下修复对我来说效果很好。

            // I am using Struts2 
            ServletContext sc = (ServletContext) ac.get(StrutsStatics.SERVLET_CONTEXT);
            fileInputStream = sc.getResourceAsStream("test.xls");
            

            部署war文件后,我可以从上下文路径中获取文件。

            【讨论】:

              【解决方案10】:

              以下解决了我的问题。

                public EHWInit()
                {
                 String resetRootPath = ""; 
              
                 try{
                 resetRootPath = this.getClass().getResource("/").getPath();
                    boolean isWinOS = System.getProperty("os.name").startsWith("Windows");
                 if( isWinOS )
                    {resetRootPath = resetRootPath.substring(1, resetRootPath.lastIndexOf("chucec"));}
                 else
                    {resetRootPath = resetRootPath.substring(0, resetRootPath.lastIndexOf("chucec"));}
              
                 resetRootPath = resetRootPath.replace("%20", " ");
                 System.out.println("EHWInit#75:resetRootPath=" + resetRootPath); 
              

              当您在操作系统为 Windows 时尝试通过 this.getClass().getResource("/").getPath() 获取 getRealPath 时,您可能会得到一个字符串如下:

              EHWInit#73:getPath=/C:/Program%20Files%20(x86)/Apache%20Software%20Foundation/Tomcat%208.5/webapps/chucec/WEB-INF/classes/

              因此,您需要对返回的字符串做一些额外的工作。此外,如果您想通过请求获取 getRealPath。您可以将代码替换如下:

                public void resetSystemPath(HttpServletRequest paramHttpServletRequest)
                {
                  //String str = paramHttpServletRequest.getRealPath("/");
              
                  HttpSession session = paramHttpServletRequest.getSession(true);
                  String str = session.getServletContext().getRealPath("/");
                  System.out.println("getRealPath:"+str);
              

              【讨论】:

                猜你喜欢
                • 2017-10-15
                • 2019-11-17
                • 2017-09-27
                • 2016-06-08
                • 2010-11-27
                • 2014-11-21
                • 1970-01-01
                • 2012-04-14
                • 2011-10-30
                相关资源
                最近更新 更多