做web開發有時會需要訪問本地檔案(例如放在web-info下面的設定檔),然而本來是一件很簡單的事情,確因tomcat和weblogic類載入機制的不同,而無法實現平台化,雖然可以利用HttpServletRequest ,request.getSession().getServletContext().getRealPath(""),但是有些地方是沒有HttpServletRequest 對象的,儘管使用其他手段例如積極式載入,事先將應用的路徑存到全域變數裡,但仍然不是很好的解決辦法,XXXX.class.getClassLoader().getResource("")這似乎是一個比較好的解決方案,但是後來我發現weblogic取的是user_projects/domains/xxx下面,而不是web-info/classes下面,因為應用的類載入器的path在這裡,與tomcat有所不同.看來只有使用XXXX.class.getResource(),這樣的話待尋找的資源必須和類在同一路徑,往往類都有包路徑例如com.xx 我們一般期望資源檔放在web-info/classes下面,於是需要一個類去解析相對路徑.例如../../這種形式.
例如取得web.xml檔案ResourceLoader.getResource("../web.xml");
ResourceLoader.getResource("../../xxx");//取得web目錄下面的xxx目錄
ResourceLoader.getResource("a.text");//取得web-info/classes/a.text
public class ResourceLoader {
private ResourceLoader() {
}
/**
*
* Description:用來載入本類所在的ClassPath的路徑下的資源檔,可以使用../符號來載入classpath外部的資源。
*
* @param relativePath
* 相當路徑
* @return URL對象
*/
public static URL getResource(String relativePath) {
URL resourceAbsoluteURL = null;
try {
relativePath = getStringForNum(ResourceLoader.class.getName()
.split("/.").length - 1, "../")
+ relativePath;
if (relativePath.indexOf("../") < 0) {
return ResourceLoader.class.getResource(relativePath);
}
String classPath = ResourceLoader.class.getResource("").toString();
if (relativePath.substring(0, 1).equals("/")) {
relativePath = relativePath.substring(1);
}
String wildcardString = relativePath.substring(0, relativePath
.lastIndexOf("../") + 3);
relativePath = relativePath.substring(relativePath
.lastIndexOf("../") + 3);
int containSum = containSum(wildcardString, "../");
classPath = cutLastString(classPath, "/", containSum);
String resourceAbsolutePath = classPath + relativePath;
resourceAbsoluteURL = new URL(resourceAbsolutePath);
} catch (Exception e) {
e.printStackTrace();
}
return resourceAbsoluteURL;
}
public File getResourceFile(String relativePath) {
try {
return new File(getResource(relativePath).getFile());
} catch (Exception e) {
return null;
}
}
/**
* 取得本類所在的classpath下面的資源檔,可以使用../符號來載入classpath外部的資源。
*
* @param relativePath
* 相當路徑
* @return 輸入資料流
*/
public static InputStream getStream(String relativePath) {
try {
return getStream(getResource(relativePath));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
*
* Description:取得本類所在的classpath下面的Properties檔案,可以使用../符號來載入classpath外部的資源。
*
* @param resource
* 相當路徑
* @return Properties 對象
*/
public static Properties getProperties(String resource) {
Properties properties = new Properties();
InputStream in = null;
try {
in = getStream(resource);
properties.load(in);
return properties;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/***************************************************************************
*
* /** 計算字串source包含dest的數目
*
* @param source
* @param dest
* @return source中包含dest的數目
*/
private static int containSum(String source, String dest) {
int containSum = 0;
int destLength = dest.length();
while (source.indexOf(dest) >= 0) {
containSum = containSum + 1;
source = source.substring(destLength);
}
return containSum;
}
/**
*
* Description:通過url取得流
*
* @param url
* @return
* @throws IOException
*/
private static InputStream getStream(URL url) {
try {
if (url != null)
return url.openStream();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 字串source從後向前去掉num個字串dest
*
* @param source
* @param dest
* @param num
* @return
*/
private static String cutLastString(String source, String dest, int num) {
for (int i = 0; i < num; i++)
source = source.substring(0, source.lastIndexOf(dest, source
.length() - 2) + 1);
return source;
}
/**
*
* Description:將指定字串str進行num次串連
*
* @param num
* @param str
* @return
*/
private static String getStringForNum(int num, String str) {
String ret = "";
for (; num > 0; num--)
ret += str;
return ret;
}
public static void main(String[] args) {
System.out.println(ResourceLoader.getResource("../web.xml"));
}
}