(转载)从读取properties文件说开去,浅谈web容器中类加载器

今天刚好有人让我写个通过读取properties连接数据库的小demo.

汗啊,普通项目中可以使用的文件读取,在web项目中总报空指针异常.

查阅了资料明白,赶紧记录下来,希望遇到此类问题的童鞋能引起重视。

废话不说,直接进入主题!

代码清单1:


01
import java.io.InputStream;
02
import java.util.Properties;
03

04
import org.apache.log4j.Logger;
05
/**
06
*
07
* 项目名称 PropertiesDemo
08
* 包 名 com.linfeng.util
09
* 文 件 名 PropertiesUtil.java
10
* 开 发 人 Administrator
11
* 描述信息 Properties文件读取类
12
* 发布日期 2012-10-31上午11:34:59
13
* 修改日期
14
* 修 改 人
15
* 版本信息 V1.0
16
*
17
*/
18
public class PropertiesUtil {
01
private static Logger log = Logger.getLogger(PropertiesUtil.class);
02
private Properties propertie;
03
private InputStream inputFile;
04
public PropertiesUtil(String filePath){
05
propertie = new Properties();
06
try {
07
inputFile = getClass().getResourceAsStream(filePath);
08
propertie.load(inputFile);
09
inputFile.close();
10
} catch (FileNotFoundException ex) {
11
log.error("读取属性文件--->失败!- 原因:文件路径错误或者文件不存在");
12
ex.printStackTrace();
13
} catch (IOException ex) {
14
log.error("装载文件--->失败!");
15
ex.printStackTrace();
16
}
17
}
18

19
/**
20
* 重载函数,得到key的值
21
* @param key 取得其值的键
22
* @return key的值
23
*/
24
public String getValue(String key)
25
{
26
if(propertie.containsKey(key)){
27
String value = propertie.getProperty(key);//得到某一属性的值
28
return value;
29
}
30
else
31
return "";
32
}//end getValue(...)
33

34
/**
35
* 重载函数,得到key的值
36
* @param fileName properties文件的路径+文件名
37
* @param key 取得其值的键
38
* @return key的值
39
*/
40
public String getValue(String fileName, String key)
41
{
42
try {
43
String value = "";
44
inputFile = getClass().getResourceAsStream(fileName);
45
propertie.load(inputFile);
46
inputFile.close();
47

48
if(propertie.containsKey(key)){
49
value = propertie.getProperty(key);
50
return value;
51
}else
52
return value;
53
} catch (FileNotFoundException e) {
54
e.printStackTrace();
55
return "";
56
} catch (IOException e) {
57
e.printStackTrace();
58
return "";
59
} catch (Exception ex) {
60
ex.printStackTrace();
61
return "";
62
}
63
}//end getValue(...)
64
/**
65
* 根据指定资源路径加载单个资源文件,返回Properties类对象的引用。
66
* 若有异常产生,则Properties类对象为空。
67
* @param filePath 资源文件的路径的值
68
* @return 给定资源文件所对应的Properties类对象的引用
69
*/
70
public static Properties loadPropertiesFile(String filePath){
71
Properties properties= new Properties();
72
InputStream is = null;
73
try {
74
try{
75
is=new FileInputStream(filePath);
76
properties.load(is);
77
}finally{
78
if (is!=null) {
79
is.close();
80
is=null;
81
}
82
}
83
} catch (Exception e) {
84
properties = null;
85
}
86
return properties;
87

88
}
89

90
}


PropertiesUtil.java 用于进行读取*.properties文件的工具类

通过方法


1
loadPropertiesFile(String filePath)
在普通java项目下可以正常读取properties文件,但是在web项目下,无法读取properties文件,报空指针异常。

这里引出类的加载器的概念

每个Class对象都保留着加载自己的类加载器的引用,可以通过Class对象的getClassLoader方法来获得其引用。ClassLoader通过loadClass方法来加载这个类。

按照类加载器,首先应该加载父类,也就是通常所说的父类优先的原则,但是在web容器中加载顺序有所不同。

通过查找资料找到这样的叙述:


对于运行在 Java EE容器中的 Web 应用来说,类加载器的实现方式与一般的 Java 应用有所不同。不同的 Web 容器的实现方式也会有所不同。以 Apache Tomcat 来说,每个 Web 应用都有一个对应的类加载器实例。该类加载器也使用代理模式,所不同的是它是首先尝试去加载某个类,如果找不到再代理给父类加载器。这与一般类加载器的顺序是相反的。这是 Java Servlet 规范中的推荐做法,其目的是使得 Web 应用自己的类的优先级高于 Web 容器提供的类。这种代理模式的一个例外是:Java 核心库的类是不在查找范围之内的。这也是为了保证 Java 核心库的类型安全。

绝大多数情况下,Web 应用的开发人员不需要考虑与类加载器相关的细节。下面给出几条简单的原则:


每个 Web 应用自己的 Java 类文件和使用的库的 jar 包,分别放在 WEB-INF/classes和 WEB-INF/lib目录下面。
多个应用共享的 Java 类文件和 jar 包,分别放在 Web 容器指定的由所有 Web 应用共享的目录下面。
当出现找不到类的错误时,检查当前类的类加载器和当前线程的上下文类加载器是否正确。


于是对于一个普通web项目,properties文件可以放在src目录下,经过编译器编译之后目录变为WEB-INF/classes目录.

路径变化后,只能通过类加载器来获得文件路径,否则无法加载。

代码清单2:


01
/**
02
*
03
* 项目名称 XXXX
04
* 包 名 com.xxx.mall.util
05
* 文 件 名 DbUtil.java
06
* 开 发 人 Administrator
07
* 描述信息 数据库帮助类
08
* <p>数据库连接方法</p>
09
* <p>释放数据库资源方法</p>
10
* 发布日期 2012-10-31下午03:26:50
11
* 修改日期
12
* 修 改 人
13
* 版本信息 V1.0
14
*
15
*/
16
public class DbUtil {
17
//Connection对象
18
private static Connection conn =null;
19
private static final String PROPERTIES_FILE_PATH="/dbconfig.properties";
20
/**
21
* 获得数据库连接对象方法
22
* @return 返回数据库连接对象conn
23
*/
24
public static Connection getConnection(){
25
try {
26
PropertiesUtil propertiesUtil=new PropertiesUtil(PROPERTIES_FILE_PATH);
27
Class.forName(propertiesUtil.getValue("driver"));
28
conn=DriverManager.getConnection(propertiesUtil.getValue("url"), propertiesUtil.getValue("user"), propertiesUtil.getValue("password"));
29
}catch (ClassNotFoundException e) {
30
throw new MyDbException("数据库jar包异常",e);
31
}catch (SQLException e) {
32
throw new MyDbException("数据库连接字符串异常",e);
33
}
34
catch (Exception e) {
35
throw new MyDbException("数据库连接异常",e);
36
}
37
return conn;
38
}
39
/**
40
* 释放数据库资源方法
41
* @param pmst
42
* @param rs
43
* @param conn
44
*/
45
public static void freeDb(PreparedStatement pmst,ResultSet rs,Connection conn){
46
if (pmst!=null) {
47
try {
48
pmst.close();
49
} catch (SQLException e) {
50
throw new MyDbException("数据库关闭PreparedStatement对象异常",e);
51
}
52
}
53
if (rs!=null) {
54
try {
55
rs.close();
56
} catch (SQLException e) {
57
throw new MyDbException("数据库关闭ResultSet对象异常",e);
58
}
59
}
60
if (conn!=null) {
61
try {
62
conn.close();
63
} catch (SQLException e) {
64
throw new MyDbException("数据库关闭Connection对象异常",e);
65
}
66
}
67
}
68

69
}



源地址:[url]http://my.oschina.net/dlpinghailinfeng/blog/86288[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值