用java web容器配置文件减少硬编码
为了减少硬编码,项目中要使用配置文件来存储一些会随部署环境变化而改变的变量值,比如说别的系统发布的子系统跳转地址等
1、利用ServletContext
servlet容器会在启动时为每个web应用创建唯一的一个 servlet context,可以把ServletContext看成一个web应用的服务器端组件的共享内存,在ServletContext中可以存放共享数据,ServletContext对象只在web应用关闭时才会被销毁,不同的Web应用,ServletContext各自独立存在,其提供的方法可以在同一web应用下的所有servlet使用。
利用ServletContext方式:
直接将配置写在web.xml中,如果需要配置的变量值比较少,放在web.xml文件中简洁明了。在web.xml文件的根节点面签的位置写下类似的配置,就可以为本web应用设置context参数:
[html]
<context-param>
<param-name>auther</param-name>
<param-value>bbbhbb</param-value>
</context-param>
获取context-param变量可以使用ServlertContext对象。Servlet中通过[getServletconfig().]getServletContext()来获取一个ServletContext对象,使用该对象的getInitParameter(String name)方法即可获取指定名称的参数。
在JSP中,application内置对象就是ServletContext。
利用ServletContext对象读取额外的资源文件。
添加额外的配置文件放到classpath中,例如db.properties,放在src的根目录下;内容如下:
[plain]
url=jdbc\:oracle\://localhost\:1521/orcl;
username=orcl;
password=123456;
假定我们获取了ServletContext对象,并保存在context变量中
[java]
ServletContext context = this.getServletContex();
我们获取资源文件有多种方式:
[java]
//1st
URL url = context.getResource("WEB-INF/classes/db.properties");
InputStream is = url.openStream();
//2nd
/*读取db.properties文件*/
String path = context.getRealPath("WEB-INF/classes/db.properties");
/*根据文件路径,创建文件对象*/
File file = new File(path);
/*根据文件对象,构建输入流*/
InputStream is = new InputStream(file);
//3rd
InputStream is = context.getResourceAsStream("WEB-INF/classes/db.properties");
得到文件流后,就可以用Properties类来对文件进行解析了 (如果配置的是xml文件,使用相应的工具进行解析)
/*解析properties文件*/
Properties prop = new Properties();
/*从输入流中读取属性列表*/
prop.load(is);
Set<String> set = prop.stringPropertyNames();
/*遍历set*/
Iterator it = set.iterator();
while(it.hasNext()){
String key = it.next();
String value = it.getProperty(key);
System.out.print("key"+key +"--------"+"value:"+value);
}
2、利用ServletConfig
config和context相比就有很大的局限性了,为一个servlet配置初始化参数可以这样写:
[html]
<servlet>
<servlet-name>DemoServlet</servlet-name>
<servlet-class>com.cn.demo.servlet</servlet-class>
<init-param>
<param-name>test</param-name>
<param-value>testvalue</param-value>
</init-param>
</servlet>
由于init-param是配置在<servlet>标签里面的,只能由这个Servlet来读取,当ServletConfig对象在servlet中被实例化后,对任何客户端的任何访问都是有效的,但是一个servlet的ServletConfig对象不能被另一个servlet访问,也就是说在本servlet中声明的ServletConfig对象只能在本servlet中访问,属于内部持久有效的变量。
配置完毕后,直接在Servlet中调用getInitParameter(String name)方法即可获得参数,也可以用ServletConfig对象来获得参数,而ServletConfig对象可通过Servlet的getServletConfig()方法获取,在jsp中,config内置对象就是ServletConfig;
3、利用Spring配置专用的常量Bean属性
在开发过程中,往往会使用一个常量类来统一封装项目中用到的所有常量,将这些常量声明为常量类的public static final属性,这样就可以随时在程序中的其他地方应用。
既然Sping的核心是IoC,那么可以用Sping来初始化这个类的static属性。由于static是类属性,不依赖实例对象,这样我们就可以达到在配置文件中配置常量的目的。
final属性初始化比较特殊,final static属性只能在静态块中初始化,或者在定义的时候进行初始化,项目中要确保没有代码会对static属性进行修改。
具体做法,声明一个普通类,定义几个public static的属性,给这几个属性设置相应的setter方法,然后在任意的sping配置文件中,配置类的初始化属性即可;
[java]
com.cn.demo.bean
public class Constants{
public static String constants1 = "A";
public static String constants2 = "A";
public static String constants3 = "A";
public static String constants4 = "A";
public static String getConstants1() {
return constants1;
}
public static void setConstants1(String Constants1) {
constants1 = Constants1;
}
public static String getConstants2() {
return constants2 ;
}
public static void setConstants2(String Constants2) {
constants2 = Constants2;
}
public static String getConstants3() {
return constants3;
}
public static void setConstants3(String Constants3) {
constants3 = Constants3;
}
public static String getConstants4() {
return constants4;
}
public static void setConstants4(String Constants4) {
constants4 = Constants4;
}
}
配置:
[html]
<bean id="constants" class="com.cn.demo.bean.Constants">
<property name="constants1">
<value>http://127.0.0.1:8080/hsirb/login.action</value>
</property>
<property name="constants2">
<value>http://127.0.0.1:8080/hsirb/login.action</value>
</property>
<property name="constants3">
<value>http://127.0.0.1:8080/hsirb/login.action</value>
</property>
<property name="constants4">
<value>http://127.0.0.1:8080/hsirb/login.action</value>
</property>
</bean>
注意Eclipse自动生成的setter方法是静态的static方法,使用Spring初始化该类时,在Spring3.0.x版本下报错:
org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'constants' defined in ServletContext resource[/WEB-INF/configs/applicationContext.xml]: Error setting property values; nestedexception is org.springframework.beans.NotWritablePropertyException: Invalidproperty 'YAGL_LOGINACTION' of bean class [com.neareast.common.Constants]: Beanproperty 'YAGL_LOGINACTION' is not writable or has an invalid setter method.Does the parameter type of the setter match the return type of the getter?
解决办法是将项目使用的spring升级到3.1.x版本,或者把setter方法的static修饰去掉即可。