基本上使用ServletContext.getRealPath() 输入参数我们都会以"/"开头,不然可能发生返回值为null的错误,但是这个错误为什么发生?原因就是基于不同容器的实现不同,或者同一容器不同版本的的实现不同所产生的问题,下面仅以mac+intellij+spring4.0.0+tomcat8.0.24为例说明,其实其他的情况大体也差不多。
找到getRealPath("XXX"),通过intellij所提示的sourcecode找到的实现细节为spring-test的包中的实现,代码中其中已经避免了参数为"XXX"会发生的错误,其代码如下:
protected String getResourceLocation(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
return this.resourceBasePath + path;
}
但是实际上,这里生效的代码并非此处所显示的代码,而是tomcat中org.apache.catalina.core包中的ApllicationContext的getRealPath方法。
这个方法在tomecat8.0.29以前是存在Bug的,尽在代码注释中写明了情况,其写到
// The WebResources API expects all paths to start with /. This is a
// special case for consistency with earlier Tomcat versions.
但是在Tomcat8.0.29以前却没有通过代码来解决,而是在参数不为空或者不以"/"开头返回null,这就导致了如标题所说的【ServletContext.getRealPath() 的输入参数要以"/"开头】的事件.
该bug在这里可以看到
https://bz.apache.org/bugzilla/show_bug.cgi?id=58228
随后在2015/3/11号的一次提交中被修复,该修复代码在15年8月发布的8.0.29版本中被发布,具体可参见
【ServletContext.getRealPath() 的输入参数要以"/"开头】事件第一阶段调查完毕。
网友评论