1.ServletContext方式
采用ServletContext读取配置文件realpath,然后通过文件流读出来。
优点:可以读取任意位置的文件
采用文件流读取,所以可以读取不同格式的文件
缺点:不能在servlet外面读取配置文件
实现:
package com.xunjie.common.utils;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Profile {
// 采用ServletContext读取配置文件的realpath,然后通过文件流读取出来
public void readProfileByServletContext(HttpServletRequest request, HttpServletResponse response) {
// 通过servletcontext读取到文件路径
String realPath = request.getServletContext().getRealPath("jdbc.properties");
//InputStream 是字节输入流的所有类的超类,一般我们使用它的子类,如FileInputStream
InputStreamReader reader;
//Properties类,主要用于读取Java的配置文件
Properties props = new Properties();
try {
// 建议使用Reader来读,因为reader体系中有个InputStreamReader可以指定编码
reader = new InputStreamReader(new FileInputStream(realPath), "utf-8");
// load ( InputStream inStream)方法
// 从输入流中读取属性列表(键和元素对)。 通过对指定的文件(比如说上面的jdbc.properties文件)进行装载来获取该文件中的所有键 - 值对。 以供 getProperty ( String key) 来搜索。
props.load(reader);
} catch (Exception e) {
e.printStackTrace();
}
// getProperty ( String key)方法,用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到 key 所对应的 value。
String jdbcUrl = props.getProperty("url");
System.out.println(jdbcUrl);
System.out.println(realPath);
}
}
使用Junit测试输出结果
Junit使用参考:https://blog.csdn.net/qq_37725650/article/details/79409589
package com.xunjie.test;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.xunjie.common.utils.Profile;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring.xml" })
public class ProfileTest {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
@Before
public void setUp() {
request = new MockHttpServletRequest();
request.setCharacterEncoding("UTF-8");
response = new MockHttpServletResponse();
}
@Test
public void test() {
System.err.println("-----测试开始-start-----");
Profile profile = new Profile();
profile.readProfileByServletContext(request, response);
System.err.println("-----测试结束-end-----");
}
}
测试结果:
-----测试开始-start-----
jdbc:mysql://127.0.0.1:3306/yeebi?useUnicode=true&&characterEncoding=UTF-8
E:\WorkSpace\xunjie\xunjie\target\classes\jdbc.properties
-----测试结束-end-----
2.通过ResourceBundle类获取配置文件资源
优点:1可以以全限定类名的方式加载资源2可以在非web应用里加载资源
缺点:只能加载类下面的资源文件,且只能读取properties文件
/**
* @Title: getProfileByResourceBundle
* @Description: 通过ResourceBundle类获取配置文件资源
* @param propertyName 配置文件名称
* 调用方式:
* 1.配置文件放在resource源包下,不用加后缀
* PropertiesUtil.getProfileByResourceBundle("message");
* 2.放在包里面的
* PropertiesUtil.getProfileByResourceBundle("com.test.message");
* @return Map 以Map键值对方式返回配置文件内容
*/
public static Map getProfileByResourceBundle(String propertyName) {
// 获得资源包
ResourceBundle rb = ResourceBundle.getBundle(propertyName.trim());
// 通过资源包拿到所有的key
Enumeration allKey = rb.getKeys();
Map profileMap = new HashMap();
// 遍历key 得到 value
while (allKey.hasMoreElements()) {
String key = allKey.nextElement();
String value = (String) rb.getString(key);
//将文件内容存入map
profileMap.put(key, value);
}
return profileMap;
}
测试运行结果:
public static void main(String[] args) {
//我的文件直接放在了src下,所以直接传入文件名称就可以了
Map profileMap = Profile.getProfileByResourceBundle("jdbc");
String jdbcUrl = profileMap.get("url");
System.out.println(jdbcUrl);
}
控制台输出:
jdbc:mysql://127.0.0.1:3306/yeebi?useUnicode=true&&characterEncoding=UTF-8
3.通过ClassLoader方式进行读取
/**
* @Title: getProfileByClassLoader
* @Description: 采用ClassLoader(类加载器)方式进行读取配置信息
* @return Map 以Map键值对方式返回配置文件内容
* 优点:可以在非Web应用中读取配置资源信息,可以读取任意的资源文件信息
* 缺点:只能加载类classes下面的资源文件
* @throws
*/
public static Map getProfileByClassLoader() {
// 通过ClassLoader获取到文件输入流对象
// 配置文件放在resource源包下,直接写文件名即可,需要后缀名"jdbc.properties"
// 放在包里面的,需要写上包路径,例如:在test包下"com/test/jdbc.properties"),Profile为当前所在类类名
InputStream in = Profile.class.getClassLoader().getResourceAsStream("jdbc.properties");
// 获取文件的位置
String filePath = Profile.class.getClassLoader().getResource("jdbc.properties").getFile();
System.out.println(filePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
Properties props = new Properties();
Map profileMap = new HashMap();
try {
props.load(reader);
for (Object key : props.keySet()) {
profileMap.put(key.toString(), props.getProperty(key.toString()));
}
} catch (IOException e) {
e.printStackTrace();
}
return profileMap;
}
测试运行结果:
public static void main(String[] args) {
Map profileMap = Profile.getProfileByClassLoader();
System.out.println(profileMap.get("url"));
}
控制台输出:
/E:/WorkSpace/xunjie/xunjie/target/classes/jdbc.properties
jdbc:mysql://127.0.0.1:3306/yeebi?useUnicode=true&&characterEncoding=UTF-8
4.使用Sping提供的PropertiesLoaderUtils类读取配置文件
当然需要导入spring核心包
/**
* @Title: getProfileByPropertiesLoaderUtils
* @Description: Spring 提供的 PropertiesLoaderUtils 允许您直接通过基于类路径的文件地址加载属性资源
* 最大的好处就是:实时加载配置文件,修改后立即生效,不必重启
* @return Map
*/
public static Map getProfileByPropertiesLoaderUtils() {
Properties props = new Properties();
Map profileMap = new HashMap();
try {
props = PropertiesLoaderUtils.loadAllProperties("jdbc.properties");
for (Object key : props.keySet()) {
profileMap.put(key.toString(), props.getProperty(key.toString()));
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
return profileMap;
}
测试运行结果:
public static void main(String[] args) {
Map profileMap = Profile.getProfileByPropertiesLoaderUtils();
System.out.println(profileMap.get("url"));
}
控制台输出:
jdbc:mysql://127.0.0.1:3306/yeebi?useUnicode=true&&characterEncoding=UTF-8
5.修改配置文件
只是修改了classes下的文件,源文件并没有改变。
/**
* 传递键值对的Map,更新properties文件
*
* @param fileName
* 文件名(放在resource源包目录下),需要后缀
* @param keyValueMap
* 键值对Map
*/
public static void updateProperties(String fileName, Map keyValueMap) {
// 输入流
// InputStream
// inputStream=PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName);
// 获取文件的路径
String filePath = Profile.class.getClassLoader().getResource(fileName).getFile();
System.out.println("propertiesPath:" + filePath);
Properties props = new Properties();
BufferedReader br = null;
BufferedWriter bw = null;
try {
// 从输入流中读取属性列表(键和元素对)
br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
props.load(br);
br.close();
// 写入属性文件
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath)));
// 清空旧的文件
// props.clear();
for (String key : keyValueMap.keySet())
props.setProperty(key, keyValueMap.get(key));
props.store(bw, "改变数据");
System.out.println(props.getProperty("url"));
bw.close();
} catch (IOException e) {
e.printStackTrace();
System.err.println("Visit " + filePath + " for updating " + "" + " value error");
} finally {
try {
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
修改前:
运行测试结果即修改后:
public static void main(String[] args) {
Profile.updateProperties("jdbc.properties", new HashMap() {
{
put("initialSize", "6");
put("test", "修改文件属性");
}
});
}