欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java web项目读取配置文件properties的3种方式

程序员文章站 2022-07-03 12:06:18
...

首先我的配置文件名称: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']}")