Java案例如何解析Properties文件?

wen java案例 19

Java案例如何解析Properties文件?一文掌握核心方法与最佳实践

📚 目录导读

  1. 什么是Properties文件?
  2. 核心解析方法详解
    • 1 传统Properties类加载
    • 2 基于ResourceBundle的国际化方案
    • 3 第三方库:Apache Commons Configuration
  3. 实战案例:从配置文件到业务逻辑
  4. 常见问题与解答(FAQ)
  5. 性能优化与安全建议

什么是Properties文件?

Properties文件是Java生态中最基础的配置格式,采用键=值的纯文本结构。

Java案例如何解析Properties文件?

# 数据库配置
db.url=jdbc:mysql://localhost:3306/mydb
db.username=root
db.password=secret

它在Spring Boot、MyBatis等框架中广泛应用,但许多开发者仅停留在“会用”层面,本文将带你从原生API到工业级方案,彻底掌握解析技巧。


核心解析方法详解

1 传统Properties类加载(原生方案)

核心步骤

Properties props = new Properties();
try (InputStream input = new FileInputStream("config.properties")) {
    props.load(input);
    String url = props.getProperty("db.url");
    System.out.println("URL: " + url);
} catch (IOException e) {
    e.printStackTrace();
}

注意事项

  • 使用try-with-resources自动关闭流(Java 7+)
  • 路径问题:建议用getClass().getResourceAsStream("/config.properties")访问classpath资源
  • 中文乱码:load()默认使用ISO 8859-1,中文需手动转码:
    props.load(new InputStreamReader(input, StandardCharsets.UTF_8));

Q1: 为什么不能直接用Properties.load()读取中文?
A: Properties类诞生于Java 1.0,当时只支持ISO 8859-1,现代项目必须显式指定UTF-8编码。

2 基于ResourceBundle的国际化方案

适用场景:多语言配置或需要根据Locale切换配置。

ResourceBundle bundle = ResourceBundle.getBundle("config", Locale.US);
String url = bundle.getString("db.url");

局限性

  • 只能读properties文件,不支持XML、YAML
  • 文件必须放在classpath根目录,且命名需遵循baseName_language_country约定

Q2: ResourceBundle和Properties类有何本质区别?
A: Properties是通用键值存储,ResourceBundle专为国际化设计,自动根据Locale匹配对应配置文件。

3 第三方库:Apache Commons Configuration(进阶方案)

引入依赖(Maven):

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-configuration2</artifactId>
    <version>2.8.0</version>
</dependency>

优势代码

Parameters params = new Parameters();
FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
    new FileBasedConfigurationBuilder<>(PropertiesConfiguration.class)
        .configure(params.fileBased()
            .setFile(new File("config.properties"))
            .setEncoding("UTF-8")
            .setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
PropertiesConfiguration config = builder.getConfiguration();
// 支持列表、层级、变量插值
String[] ips = config.getStringArray("server.ips"); 
String dbUrl = config.getString("db.url");

Q3: 为什么推荐用Commons Configuration而非原生API?
A: 它提供自动重载(AutoSave)、变量插值(${sys:user.home})、多格式支持(XML、YAML)等功能,适合中大型项目。


实战案例:从配置文件到业务逻辑

场景:解析一个业务规则配置文件,实现动态开关功能。
config.properties

feature.new-login.enabled=true
feature.payment.timeout=3000
feature.blacklist=192.168.1.1,10.0.0.1

解析代码

public class FeatureConfig {
    private static final Properties props = new Properties();
    static {
        try (InputStream is = FeatureConfig.class.getResourceAsStream("/features.properties")) {
            props.load(new InputStreamReader(is, StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException("Failed to load features config", e);
        }
    }
    public static boolean isNewLoginEnabled() {
        return Boolean.parseBoolean(props.getProperty("feature.new-login.enabled", "false"));
    }
    public static List<String> getBlacklist() {
        String raw = props.getProperty("feature.blacklist", "");
        return Arrays.asList(raw.split(","));
    }
}

调用

if (FeatureConfig.isNewLoginEnabled()) {
    // 处理新登录逻辑
}

Q4: 如何避免每次读取都解析文件?
A: 使用静态初始化(如上述代码),或借助Guava Cache实现定时刷新。


常见问题与解答(FAQ)

Q5: Properties文件中的注释支持哪些格式?

A: 仅支持行首的或,不支持行尾注释。

# 这是正确注释
key=value # 这是错误用法(会被解析为值的一部分)

Q6: 如何安全存储数据库密码等敏感信息?

A: 不要明文存储!方案:

  1. 使用Jasypt加密库进行可逆加密
  2. 结合Spring Cloud Config的加密功能
  3. 环境变量+系统属性覆盖(System.getProperty()

Q7: 解析时出现java.lang.IllegalArgumentException: Key contains blank怎么办?

A: 检查值中是否混入空格,如key = value(等号前后空格会被忽略,但键内部不能有空格)。


性能优化与安全建议

性能优化

  • 缓存策略:对于低频变更的配置,使用静态缓存(如ConcurrentHashMap)
  • 懒加载:只有在首次访问配置时才加载文件
  • 避免频繁IO:使用watchService监听文件变化,而非每次请求都重新读取

安全最佳实践

  • 文件权限:配置文件设置600(仅所有者读写)
  • 避免硬编码:所有配置路径应外部化,通过环境变量传递
  • 敏感信息加密:密码使用AES加密后存储,运行时注入解密密钥

从原生Properties类到Commons Configuration,再到企业级加密与缓存,解析Properties文件远不止load()一个方法,掌握这些技巧,你不仅能高效处理配置,还能写出更健壮、可维护的Java应用。

拓展阅读:如果你正在使用Spring Boot,请优先考虑@ConfigurationProperties注解,它能自动绑定配置文件到Java对象,实现类型安全配置。

抱歉,评论功能暂时关闭!