如何获取web应用的部署路径(多种方式)

我们用java做web应用的时候,最后会部署到服务器中,一般就是一个war包,或者是ear包。同时,我们常常需要读取一些固定路径的文件内容,比如针对某个功能的配置文件,比如某个jar包中的文件等。当我们需要做到这些的前提,就是知道文件或者jar的决定路径,这样我们可以通过File的API来获取其中的内容。

获取一个web应用的部署路径,一般有2种方式:

1.从request中获取,也就是当客户端向服务端发送请求时,截取其中的请求路径中内容来获取应用的部署路径,这是一种常用的方法。下面以jsf的请求为例

war包部署的路径:
    public static String getDeployWarPath() {
        FacesContext ctx = FacesContext.getCurrentInstance();
        String deployPath = ((ServletContext) ctx.getExternalContext().getContext()).getRealPath("/");
        if (!deployPath.endsWith(String.valueOf(File.separatorChar)))
            deployPath += File.separatorChar;
        if (deployWarPath == null) {
            deployWarPath = deployPath;
        }
        return deployPath;
    }

ear包部署的路径:

    public static String getDeployEarPath() {
        String deployPath = getDeployWarPath();
        deployPath = deployPath.substring(0, deployPath.lastIndexOf(File.separatorChar));
        deployPath = deployPath.substring(0, deployPath.lastIndexOf(File.separatorChar));
        deployPath = deployPath + File.separatorChar;
        return deployPath;
    }

这种获取方式有一个致命缺陷,就是需要应用启动运行,并且有请求发生时,才能从servlet中获取,一旦你需要在应用启动的时候获取,那么就无能为力了,下面介绍第二种获取方式

2.通过java的类加载获取

我们都知道,java虚拟机会将java文件编译成.class文件。对于一个web应用,这些文件有2个去处。src下面的会被存放到WEB-INF\classes文件夹下面,如果是关联jar的方式,那么会被编译成.class的jar包,放到WEB-INF\lib下面,java的类加载机制决定了我们可以通过这种途径来获取。

public class JsfHelper
{

    public static String deployWarPath = null;

    static {
        URL url = JsfHelper.class.getResource("JsfHelper.class");
        String temppath = url.toString();
        int startIndex = temppath.indexOf("file:");
        int index = temppath.indexOf("WEB-INF");
        deployWarPath = temppath.substring(startIndex + "file:".length() + 1, index);
        // 如果是linux的操作系统,并且开始没有file分隔符的话,那么要加上
        if (System.getProperty("os.name").indexOf("Linux") != -1) {
            if (!deployWarPath.startsWith(File.separator)) {
                deployWarPath = File.separator + deployWarPath;
            }
        }
    }

}

在JsfHelper类里面有个静态代码区,这块static包含的代码会在类加载的时候运行仅有的一次,一般我们为了兼容windows和linux,file的分隔符不会写死/,而是会写成File.separator ,同时上面那段代码有个针对linux的特殊处理,linux上路径以分隔符开始,windows下面是以盘名开始的,有点不一样。

原文地址:https://www.cnblogs.com/komojoemary/p/2259503.html