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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/536228/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:56:48  来源:igfitidea点击:

Why does getRealPath() return null when deployed with a .war file?

javaxmljspjakarta-ee

提问by musicking123

getRealPath()is returning the actual path in the local system, but returns null when deployed with a .warfile.

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>

Can anyone provide me with an alternative for this? It would be very helpful if you showed some sample code too.

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

回答by David Grant

For a start, ServletRequest.getRealPath(String path)is deprecated. The appropriate replacement is:

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

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

However, the API docs for ServletContext.getRealPath(String path)state:

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

"This method returns nullif the servlet container cannot translate the virtual path to a real path for any reason (such as when the content is being made available from a .war archive)."

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

So the API is fulfilling its contract! However, all is not lost, as you can load a resource from the WAR using the following method, as defined in ServletContext:

所以 API 正在履行它的契约!但是,一切都没有丢失,因为您可以使用以下方法从 WAR 加载资源,如ServletContext 中所定义:

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

回答by krosenvold

I do not believe it is possible to do what you're trying to do.

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

You should use getResource to read the xml file from inside your war file (this also works without war)

您应该使用 getResource 从您的战争文件中读取 xml 文件(这也适用于没有战争)

servletContext.getResourceAsStream("/generate.xml")

The leading slash depends on where the generate.xml is stored.

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

回答by skr

Take note context.getRealPath()can return null when there is user permission problem, check Web server running under which user.

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

回答by VnMa

I had the same problems too. Calling getRealPath() return null when deployed to a standalone server. After searching around for a while, I found the solution for this, it's not in the code. It's in the config of your web server.

For me it's Weblogic 10.3, you go to Home - - Configuration - Web Application, set Archived Real Path Enabled to true. Restart server and everything works fine.

Hope this help, Regards.

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

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

希望这有帮助,问候。

回答by user2094587

do you use Weblogic?

你使用 Weblogic 吗?

If yes - then this is a Weblogic issue which you may fix in Weblogic admin console ->Domain->Web Applications - click the checkbox "Archived Real Path Enabled".

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

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

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

回答by Saravanan Sagadevan

The following fix working fine for me.

以下修复对我来说工作正常。

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

After deployed war file, I am able to get the file from the context path.

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

回答by Vishnudev K

if you want to write into

如果你想写入

use

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

to get the path

获取路径

回答by Liam Dempsey

Bit late, but I came across this question when I was having this issue in WebLogic. My solution was to add this to my weblogic.xml:

有点晚了,但是当我在 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>

I found this solution better for when you don't want to (or can't) edit the configuration on the WebLogic server.

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

回答by user5101998

This solves the problem also:

这也解决了这个问题:

weblogic.xml

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>

回答by dtchang.tw

The following fix my problem.

以下解决了我的问题。

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

When you try to get getRealPathby this.getClass().getResource("/").getPath()when OS is Windows, then you may get a string like following:

当你试图让getRealPath通过。this.getClass()的getResource(“/”)的getPath()时,操作系统是Windows,那么你可能会得到像下面的字符串:

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

Therefor, you need do some extra works on the returning string.Furthermore, if you want to get getRealPathby request. You can replace the code like follows:

因此,您需要对返回的字符串做一些额外的工作。此外,如果您想通过请求获取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);