java web项目读取配置文件properties的3种方式
首先我的配置文件名称:cdsssms.properties,内容如下:
ORDER_URL=http://xx.xx.x.x:8888/sms.aspx
USER_ID=311147
ACCOUNT_NO=kp11l
ACCOUNT_PASSWORD=10003451
1、第一种使用文件流方式读取。
读取多个properties文件的例子。此例子直接可以用于到项目中。
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @Description:Properties配置文件工具
*
*/
public class ConfigUtil {
private static Logger logger = LoggerFactory.getLogger(ConfigUtil.class);//日志
final static Properties props = new Properties();//配置文件对象
static String rootPath= "";
/**加密项目的文件路径**/
public static final String IMAGEURl = ConfigUtil.getGetProperties("parameter").getProperty("imagePath").toString();
public static final String PAGE_DIR = ConfigUtil.getGetProperties("parameter").getProperty("pageDir").toString();
public static final String CLASS_DIR = ConfigUtil.getGetProperties("parameter").getProperty("classDir").toString();
public static final String PROJECT_NAME = ConfigUtil.getGetProperties("parameter").getProperty("projectName").toString();
public static final String PROJECT_URL = ConfigUtil.getGetProperties("parameter").getProperty("projectUrl").toString();
/**短信通道的参数**/
public static final String ORDER_URL = ConfigUtil.getGetProperties("cdsssms").getProperty("ORDER_URL").toString();
public static final String USER_ID = ConfigUtil.getGetProperties("cdsssms").getProperty("USER_ID").toString();
public static final String ACCOUNT_NO = ConfigUtil.getGetProperties("cdsssms").getProperty("ACCOUNT_NO").toString();
public static final String ACCOUNT_PASSWORD = ConfigUtil.getGetProperties("cdsssms").getProperty("ACCOUNT_PASSWORD").toString();
/**
*
* @Description:得到Properties配置文件
* @param propertiesName(配置文件路径)
* @param programName 项目名
* @throws
*/
public static Properties getGetProperties(String propertiesName, String programName){
String url = getUrl(programName);
setPro(url, propertiesName);
return props;
}
/**
*
* @Title: getGetPropertiesByClass
* @Description: 通过class类得到当前配置文件路径
* @param cls
* @param propertiesName
* @return Properties
* @author ganjing
* @throws
*/
public static Properties getGetPropertiesByClass(Class<?> cls, String propertiesName){
String url = getClassUrl(cls);
setPro(url, propertiesName);
return props;
}
/**
*
* @Description:得到Properties配置文件
* @param propertiesName 配置文件中的属性名称
* @return Properties
* @throws
*/
public static Properties getGetPropertiesForJar(String propertiesName){
String url = getUrlForJar();
setPro(url, propertiesName);
return props;
}
/**
*
* @Description: 获得classpath基础路径
*
* @return
*/
private static String getUrl(String programName) {
rootPath = ConfigUtil.class.getResource("").toString();
String url = null;
if (System.getProperty("os.name").toLowerCase().indexOf("window") > -1) {
url = rootPath.replace("file:/", "").replace("%20", " ")
.split("/com")[0];
} else {
url = rootPath.replace("file:", "").replace("%20", " ")
.split("/com")[0];
}
String separator = "/";
String url1 = url.substring(0, url.lastIndexOf(separator));
String url2 = url.substring(url1.lastIndexOf(separator), url1.length());
url1 = url1.substring(0, url1.lastIndexOf(separator));
url1 = url1.substring(0, url1.lastIndexOf(separator));
String url3 = url.substring(url.lastIndexOf(separator), url.length());
return url1 + File.separator + programName+ url2+url3;
}
private static String getClassUrl(Class<?> cls) {
return cls.getClassLoader().getResource("").getPath();
}
/**
*
* @author jl
* @Description: 返回jar运行同级目录config
* @date:2017年3月13日 下午4:21:00
* @return
*/
private static String getUrlForJar() {
return "config";
}
/**
*
* @Description: 获得properties文件
* @date:2017年3月13日 下午4:26:36
*/
private static void setPro(String url, String propertiesName) {
FileInputStream fileIo = null;
BufferedInputStream bufferIo = null;
try {
fileIo = new FileInputStream(url+File.separator+propertiesName+".properties");
bufferIo = new BufferedInputStream(fileIo);
props.load(bufferIo);
} catch (Exception e) {
logger.error("读取项目的配置文件加载异常:{}",e);
} finally {
try {
fileIo.close();
bufferIo.close();
} catch (IOException e) {
logger.error("读取项目的配置文件加载异常:{}",e);
try {
bufferIo.close();
} catch (IOException e1) {
logger.error("读取项目的配置文件加载异常:{}",e1);
}
}
}
}
/**
*
* @Description:得到Properties配置文件
* @param propertiesName 配置文件的名称
* @return Properties 配置文件中的数据
* @throws
*/
public static Properties getGetProperties(String propertiesName){
rootPath = ConfigUtil.class.getResource("").toString();
String url = null;
if (System.getProperty("os.name").toLowerCase().indexOf("window") > -1) {
url = rootPath.replace("file:/", "").replace("%20", " ")
.split("/com")[0];
} else {
url = rootPath.replace("file:", "").replace("%20", " ")
.split("/com")[0];
}
FileInputStream fileIo = null;
BufferedInputStream bufferIo = null;
try {
fileIo = new FileInputStream(url+File.separator+propertiesName+".properties");
bufferIo = new BufferedInputStream(fileIo);
props.load(bufferIo);
} catch (Exception e) {
logger.error("读取项目的配置文件加载异常:{}",e);
} finally {
try {
fileIo.close();
bufferIo.close();
} catch (IOException e) {
logger.error("读取项目的配置文件加载异常:{}",e);
try {
bufferIo.close();
} catch (IOException e1) {
logger.error("读取项目的配置文件加载异常:{}",e1);
}
}
}
return props;
}
}
要看更详细的原理介绍请参考链接地址:https://www.cnblogs.com/super-yu/p/8622463.html
2、第二种使用PropertyPlaceHolderConfigurer
spring项目的配置文件具体配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 使用注解注入properties中的值 -->
<bean id="SDKConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- ignoreUnresolvablePlaceholders为是否忽略不可解析的 Placeholder,如配置了多个PropertyPlaceholderConfigurer,则需设置为true -->
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:/config/${package.env}/mobile.properties</value>
<value>classpath:/config/${package.env}/db.properties</value>
<value>classpath:/config/${package.env}/cdsssms.properties</value>
</list>
</property>
<!-- 设置编码格式 -->
<property name="fileEncoding" value="UTF-8"></property>
</bean>
</beans>
开始我把@Value("${msg.send.url}")用在controller的一个类中使用。报错:
Error creating bean with name 'creditCardPaymentController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private java.lang.String com.qingyu.pay.mobile.controller.CreditCardPaymentController.smsOrderUrl;
根据报错:在我的creditCardPaymentController中短信配置文件注入失败,证明spring加载配置文件都没有加载成功。然后查检项目的配置文件:
<context:component-scan base-package="com.xxxxx.xxx">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
发现我没有把controller包放入component-scan中扫描。所以报此错。一般配置文件的使用引入到Service层中使用。所以我创建了一个Service类,代码如下:
@Service("sendMsgService")
public class SendMsgService {
private static final Logger logger = LoggerFactory.getLogger(SendMsgService.class);
@Value("${ORDER_URL}")
private String smsOrderUrl;
@Value("${USER_ID}")
private String smsUserID;
@Value("${ACCOUNT_NO}")
private String smsAccountNo;
@Value("${ACCOUNT_PASSWORD}")
private String smsPassword;
public String sendSmsRequest(){
logger.info("短信发送的userId:{},accountNo:{},password:{},url:{}",smsUserID,smsAccountNo,smsPassword,smsOrderUrl);
return "";
}
}
要深入了解PropertyPlaceHolderConfigurer的实现原理请参考以下blog:
https://www.cnblogs.com/fnlingnzb-learner/p/10384742.html
https://blog.csdn.net/u013789656/article/details/80937687
https://blog.csdn.net/CSDN19951017/article/details/84031375
3、第三种使用PropertiesFactoryBean
使用格式:@Value("#{SDKConfig['xf.payDF.url']}")
spring项目配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 使用注解注入properties中的值 -->
<bean id="SDKConfig" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<array>
<value>classpath:xf-sdk.properties</value>
<value>classpath:xfx-sdk.properties</value>
<value>classpath:dd-sdk.properties</value>
<value>classpath:prop.properties</value>
</array>
</property>
<!-- 设置编码格式 -->
<property name="fileEncoding" value="UTF-8"></property>
</bean>
</beans>
Service类的代码:
@Service("sendMsgService")
public class SendMsgService {
private static final Logger logger = LoggerFactory.getLogger(SendMsgService.class);
@Value("#{SDKConfig['ORDER_URL']}")
private String smsOrderUrl;
@Value("#{SDKConfig['USER_ID']}")
private String smsUserID;
@Value("#{SDKConfig['ACCOUNT_NO']}")
private String smsAccountNo;
@Value("#{SDKConfig['ACCOUNT_PASSWORD']}")
private String smsPassword;
public String sendSmsRequest(){
logger.info("短信发送的userId:{},accountNo:{},password:{},url:{}",smsUserID,smsAccountNo,smsPassword,smsOrderUrl);
return "";
}
}
参考链接代码:https://blog.csdn.net/qq_1017097573/article/details/62897645
总结:PropertyPlaceholderConfigurer 与PropertiesFactoryBean 区别:
使用 PropertyPlaceholderConfigurer 时, @Value表达式的用法是 @Value(value="${properties key}") ,
使用 PropertiesFactoryBean 时,我们还可以用@Value 读取 properties对象的值, @Value 用法 是 @Value(value="#{configProperties['properties key']}")
下一篇: 大型网站到了需要做改变的时候
推荐阅读
-
细数Java项目中用过的配置文件(properties篇)
-
Java语言读取配置文件config.properties的方法讲解
-
Java Web的Maven项目中Properties文件的使用
-
Web项目中java类读取WebRoot目录下的配置文件
-
java web项目读取配置文件properties的3种方式
-
java web项目获取src和WebContent目录下的配置文件
-
配置文件的几种读取方式(Java和Lua)
-
详解Java程序读取properties配置文件的方法
-
对Java配置文件Properties的读取、写入与更新操作
-
java Properties读取配置文件时的相对路径