做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
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 " ));
}
}