获取tomcat中工程的绝对路径

来源:互联网 发布:淘宝推荐系统架构 编辑:程序博客网 时间:2024/05/21 10:15

前几天遇到一个问题:

         我接到一个任务,一个web工程的图片获取问题。在这个工程中原来的图片获取方式是:jsp发送一个请求到服务器,然后服务器根据请求在数据中找到图片的相对路径,然后在工程中有个工具类中有一个常量保存了本地图片文件夹的绝对路径,将这个相对路径接在在这个绝对路径上,获得这张图片在本地上的绝对路径,再用一个I/O流通过文件的方式获取图片,再返回一个流到jsp中显示。

 

    源文件中的常量就是这么声明的:

public static final String ATT_PATH = "G:/Program Files/apache-tomcat-7.0.23/webapps/anjisi/attached/";

    public static final String PIC_PATH = "G:/Program

 Files/apache-tomcat-7.0.23/webapps/anjisi/data/images/";

我需要让这个常量根据不同的主机动态设置

 

         问题就出现了,将这个工程布置到另一台主机上,图片在主机上的绝对路径也许就不同了,应此就需要修改工具类中的常量的值。因此在不同的主机上开发,就要修改成不同的值,在团队开发中版本控制时就会一些奇葩的bug。现在我将这个路径变成动态获取此时本地图片的路径。

 

    为了实现这个需求,我用了接近两天时间(我比较笨,写这篇文章的目的就是记录一下这个心酸的过程)。

 

    我最开始想到的方法就是书写一个类来获取当前系统中工程的路径,然后再对图片进行定位,我的源文件是这么写的:

import java.io.File;

 

public class Test{

    public String path = null;

    public Test() {

        path = new File("").getAbsolutePath().replaceAll("\\\\""/");

    }

    public String getPath() {

        return path;

    }

    public void setPath(String path) {

        this.path = path;

    }

    public static void main(String[] args) {

        System.out.println(new Test().getPath());

    }

}

 

然后常量的设置修改为:

public static final String ATT_PATH = new Test().getPath()+" /webapps/anjisi/attached/";

    public static final String PIC_PATH = new Test().getPath()+" /webapps/anjisi/data/images/";

 

    但是,当我重启tomcat后,发现在页面中就没有图片了,我意识到这个地方有问题。我开始还以为是在我写的那个获取路径的类出了问题,我以为是利用文件的方式获取路径有问题,所以我换了一个方法,我使用System去获取路径,代码为:

path = new File("").getAbsolutePath().replaceAll("\\\\""/");

改为:

path = System.getProperty("user.dir").replaceAll("\\\\""/");

 

    但是写成这样还是不能正常显示图片,在此,我迷茫了,我不知道问题在哪儿了。直到晚上大神回来看到代码给我说,这个常量除了问题,用我这种方式进行动态常量赋值,常量将不再是常量来,即使用了static final 进行约束,因为这个值在系统运行的过程中在不断的进行重新设置,即使值没有变化,也是在不断的重新设置。所以我就在思考怎么让这个值在启动tomcat时就确定下来,在后面系统运行是就不再重新设置。在第二天的一趟课上,觉得课程无聊打算睡觉,刚趴下灵光就出现了,我在想可以使用一个action 或 filter来进行路径设置,只需在首次进入网站的时候就进行配置。下课后我就去了公司,跟公司的指导老师说了我的想法,他让我自己做一下测试,然而在我准备做测试的时候,我想到了这个想法中存在的问题:这个方法是行不通的,因为这是从客服端进行思考的,没有考虑到服务器是一只运行的,只要服务器在运行,用户进入系统时就进行一次设置,如果有成千上万过用户在短时间内进入系统,那么在服务器上看来,这个常量还是在不断的重新设置。于是在推翻了这个想法后,我要重新思考新的处理方案,但是这个点子并不是一无所获,我又想到了一个方法,就是:在服务器启动这个工程的时候,首先执行一段程序,这段程序就是获取这个工程此时在服务器上的路径,然后保存下来,再对常量进行设置,这样处理在后面工程运行的过程中,系统将不会再次获取工程所在的路径,而是在工程中的一个常量中直接获取。于是,我查找了相关资料,其中一个方法就是书写一个servlet,在tomcat启动时首先执行这个servlet,而这个servlet仅仅执行一次。这个方法可以实现我的想法,我立即书写了代码,源代码是:

import javax.servlet.http.HttpServlet;

 

public class AutoPathServlet extends HttpServlet {

    public static String path = null;

    public void init(){

path = this.getServletConfig().getServletContext(). getRealPath("/").replaceAll("\\\\""/");

    }

}

 

在web.xml中配置这个servlet的代码是:

<servlet>

    <servlet-name>pathInit</servlet-name>

    <servlet-class>com.example.dev.web.servlet.AutoPathServlet</servlet-class>

    <load-on-startup>1</load-on-startup><!—这个“1”很重要-->

    </servlet>

 

常量的设置方式代码是:

public static final String ATT_PATH = AutoPathServlet.path+"data/attachment/";

public static final String PIC_PATH = AutoPathServlet.path+"data/images/";

 

实现证明,这个方法可行!

 

经过这么多周折,这个问题终于解决了。

0 0
原创粉丝点击