我们都知道,通过ServletContext类可以获取工程路径(虚拟路径)以及工程部署在服务器硬盘上的绝对路径

那我们首先应该了解一个工程是怎样部署的,以idea为例

不知道大家有没有发现每当我们启动服务器时,都会有这样一个地址

这是一个什么地址呢,我们打开发现它的目录内容如下

image-20211027224012331

有没有熟悉感?我们对比一下Tomcat的目录Tomcat目录

发现了吗,这个路径其实就是IDEA整合Tomcat之后,Tomcat被拷贝的一些副本内容。

进入这个地址的conf/Catalina/localhost目录,我们发现了这样一个文件

idea整合Tomcat地址中配置文件内容

回想一下conf/Catalina/localhost这个路径,我们使用tomcat部署项目的第三种方式是不是也是在这个路径下创建一个.xml的配置文件

显而易见idea部署项目时使用的其实就是第三种tomcat部署项目的方式

因为我们不可能每次创建工程在tomcat的webapps目录下,所以idea会根据我们设置的工程部署路径以及虚拟路径生成出一个配置文件

下图分别为我们设置的虚拟路径以及工程部署路径

虚拟路径

工程路径

然后每当我们部署项目时,就会创建我们所设置的工程部署路径,随后我们在网站访问的其实都是该路径下的内容而不是开发环境文件夹下的内容,但两者内容其实一样,工程部署路径的内容是完全拷贝开发环境中web文件夹下的内容

这样就解释了为什么context.getRealPath(“/”)获得的路径为什么和我们项目创建的路径不一样(因为获取的是工程的部署路径)

public class ContextServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取配置文件中的上下文参数
        ServletContext context = getServletConfig().getServletContext();
        System.out.println(context.getContextPath());
        System.out.println("当前工程部署的路径" + context.getRealPath("/"));
        System.out.println(context.getRealPath("/css"));
        System.out.println(context.getRealPath("/jpg"));
    }

}

上述程序执行后返回结果如下

/myfirst
当前工程部署的路径E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded
E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded\css
E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded\jpg

context.getContextPath()获得工程路径,故输出/myfirst

context.getRealPath(“/”)获得参数所对应虚拟路径的真实路径

其中“/”表示根目录,项目工程的根目录,即http://ip:port/工程路径

那么context.getRealPath(“/”)也就是获得工程的真实路径,即工程部署的物理位置

自然也就是上文配置文件中的docBase值

Q.E.D.


   七岁几胆敢预言自己,操一艘战机