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