使用.war文件部署时,为什么getRealPath()返回null?

时间:2009-02-11 10:21:14

标签: java xml jsp java-ee

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>

任何人都可以为我提供替代方案吗? 如果您也展示了一些示例代码,那将非常有用。

10 个答案:

答案 0 :(得分:36)

首先,不推荐使用ServletRequest.getRealPath(String path)。适当的替代是:

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

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

  

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

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

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

答案 1 :(得分:17)

有点晚了,但是当我在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服务器上的配置时,我发现此解决方案更好。

答案 2 :(得分:6)

你使用Weblogic吗?

如果是 - 那么这是一个Weblogic问题,您可以在Weblogic管理控制台中修复 - &gt; Domain-&gt; Web应用程序 - 单击“已存档的实际路径”复选框。

请参阅:http://ananthkannan.blogspot.com/2009/12/servletcontextgetrealpath-returns-null.html

答案 3 :(得分:3)

这也解决了这个问题:

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>

答案 4 :(得分:2)

我不相信你可以做你想做的事情。

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

servletContext.getResourceAsStream("/generate.xml")

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

答案 5 :(得分:2)

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

对我来说,它是Weblogic 10.3,你转到Home - - Configuration - Web Application,将Archived Real Path Enabled设置为true。重启服务器,一切正常。

希望这有帮助, 问候。

答案 6 :(得分:2)

如果你想写入

使用

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

获取路径

答案 7 :(得分:1)

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

答案 8 :(得分:0)

以下修复对我来说很好。

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

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

答案 9 :(得分:-1)

以下解决了我的问题。

  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); 

当您尝试通过 this.getClass()获取 getRealPath 。当操作系统是Windows时,getResource(&#34; /&#34;)。getPath() ,那么你可能得到一个如下字符串:

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);