如何用Java案例实现配置文件解析?

wen java案例 3

本文目录导读:

如何用Java案例实现配置文件解析?

  1. 项目结构
  2. 配置文件示例
  3. 配置模型类
  4. 解析器接口和实现
  5. 主程序入口
  6. Maven依赖
  7. 运行结果示例
  8. 主要特点

我来用一个完整的Java案例来演示配置文件解析的几种常见方式。

项目结构

config-parser-demo/
├── src/main/java/com/example/config/
│   ├── parser/
│   │   ├── ConfigParser.java
│   │   ├── PropertiesParser.java
│   │   ├── JsonParser.java
│   │   └── YamlParser.java
│   ├── model/
│   │   └── AppConfig.java
│   └── Main.java
└── src/main/resources/
    ├── application.properties
    ├── application.json
    └── application.yaml

配置文件示例

application.properties

# 应用配置
app.name=ConfigDemo
app.version=1.0.0
app.description=配置文件解析示例
# 数据库配置
db.host=localhost
db.port=3306
db.username=root
db.password=123456
db.database=test
# 服务器配置
server.port=8080
server.host=0.0.0.0
server.ssl.enabled=false
# 缓存配置
cache.type=redis
cache.timeout=3600
cache.max.size=1000

application.json

{
  "app": {
    "name": "ConfigDemo",
    "version": "1.0.0",
    "description": "配置文件解析示例"
  },
  "database": {
    "host": "localhost",
    "port": 3306,
    "username": "root",
    "password": "123456",
    "database": "test"
  },
  "server": {
    "port": 8080,
    "host": "0.0.0.0",
    "ssl": {
      "enabled": false
    }
  },
  "cache": {
    "type": "redis",
    "timeout": 3600,
    "maxSize": 1000
  }
}

application.yaml

app:
  name: ConfigDemo
  version: 1.0.0
  description: 配置文件解析示例
database:
  host: localhost
  port: 3306
  username: root
  password: 123456
  database: test
server:
  port: 8080
  host: 0.0.0.0
  ssl:
    enabled: false
cache:
  type: redis
  timeout: 3600
  maxSize: 1000

配置模型类

package com.example.config.model;
import java.util.Map;
public class AppConfig {
    private String appName;
    private String appVersion;
    private String appDescription;
    private String dbHost;
    private int dbPort;
    private String dbUsername;
    private String dbPassword;
    private String dbDatabase;
    private int serverPort;
    private String serverHost;
    private boolean sslEnabled;
    private String cacheType;
    private int cacheTimeout;
    private int cacheMaxSize;
    // 用于存储额外的配置项
    private Map<String, Object> additionalConfig;
    // Getters and Setters
    public String getAppName() { return appName; }
    public void setAppName(String appName) { this.appName = appName; }
    public String getAppVersion() { return appVersion; }
    public void setAppVersion(String appVersion) { this.appVersion = appVersion; }
    public String getAppDescription() { return appDescription; }
    public void setAppDescription(String appDescription) { this.appDescription = appDescription; }
    public String getDbHost() { return dbHost; }
    public void setDbHost(String dbHost) { this.dbHost = dbHost; }
    public int getDbPort() { return dbPort; }
    public void setDbPort(int dbPort) { this.dbPort = dbPort; }
    public String getDbUsername() { return dbUsername; }
    public void setDbUsername(String dbUsername) { this.dbUsername = dbUsername; }
    public String getDbPassword() { return dbPassword; }
    public void setDbPassword(String dbPassword) { this.dbPassword = dbPassword; }
    public String getDbDatabase() { return dbDatabase; }
    public void setDbDatabase(String dbDatabase) { this.dbDatabase = dbDatabase; }
    public int getServerPort() { return serverPort; }
    public void setServerPort(int serverPort) { this.serverPort = serverPort; }
    public String getServerHost() { return serverHost; }
    public void setServerHost(String serverHost) { this.serverHost = serverHost; }
    public boolean isSslEnabled() { return sslEnabled; }
    public void setSslEnabled(boolean sslEnabled) { this.sslEnabled = sslEnabled; }
    public String getCacheType() { return cacheType; }
    public void setCacheType(String cacheType) { this.cacheType = cacheType; }
    public int getCacheTimeout() { return cacheTimeout; }
    public void setCacheTimeout(int cacheTimeout) { this.cacheTimeout = cacheTimeout; }
    public int getCacheMaxSize() { return cacheMaxSize; }
    public void setCacheMaxSize(int cacheMaxSize) { this.cacheMaxSize = cacheMaxSize; }
    public Map<String, Object> getAdditionalConfig() { return additionalConfig; }
    public void setAdditionalConfig(Map<String, Object> additionalConfig) { 
        this.additionalConfig = additionalConfig; 
    }
    @Override
    public String toString() {
        return "AppConfig{" +
                "appName='" + appName + '\'' +
                ", appVersion='" + appVersion + '\'' +
                ", appDescription='" + appDescription + '\'' +
                ", dbHost='" + dbHost + '\'' +
                ", dbPort=" + dbPort +
                ", dbUsername='" + dbUsername + '\'' +
                ", serverPort=" + serverPort +
                ", serverHost='" + serverHost + '\'' +
                ", sslEnabled=" + sslEnabled +
                ", cacheType='" + cacheType + '\'' +
                ", cacheTimeout=" + cacheTimeout +
                ", cacheMaxSize=" + cacheMaxSize +
                '}';
    }
}

解析器接口和实现

接口定义

package com.example.config.parser;
import com.example.config.model.AppConfig;
public interface ConfigParser {
    AppConfig parse(String filePath) throws Exception;
    ConfigType getType();
    enum ConfigType {
        PROPERTIES,
        JSON,
        YAML
    }
}

Properties解析器

package com.example.config.parser;
import com.example.config.model.AppConfig;
import java.io.*;
import java.util.*;
public class PropertiesParser implements ConfigParser {
    @Override
    public AppConfig parse(String filePath) throws Exception {
        Properties props = new Properties();
        AppConfig config = new AppConfig();
        Map<String, Object> additionalConfig = new HashMap<>();
        try (InputStream input = new FileInputStream(filePath)) {
            props.load(input);
            // 解析应用配置
            config.setAppName(props.getProperty("app.name"));
            config.setAppVersion(props.getProperty("app.version"));
            config.setAppDescription(props.getProperty("app.description"));
            // 解析数据库配置
            config.setDbHost(props.getProperty("db.host"));
            if (props.containsKey("db.port")) {
                config.setDbPort(Integer.parseInt(props.getProperty("db.port")));
            }
            config.setDbUsername(props.getProperty("db.username"));
            config.setDbPassword(props.getProperty("db.password"));
            config.setDbDatabase(props.getProperty("db.database"));
            // 解析服务器配置
            if (props.containsKey("server.port")) {
                config.setServerPort(Integer.parseInt(props.getProperty("server.port")));
            }
            config.setServerHost(props.getProperty("server.host"));
            if (props.containsKey("server.ssl.enabled")) {
                config.setSslEnabled(Boolean.parseBoolean(props.getProperty("server.ssl.enabled")));
            }
            // 解析缓存配置
            config.setCacheType(props.getProperty("cache.type"));
            if (props.containsKey("cache.timeout")) {
                config.setCacheTimeout(Integer.parseInt(props.getProperty("cache.timeout")));
            }
            if (props.containsKey("cache.max.size")) {
                config.setCacheMaxSize(Integer.parseInt(props.getProperty("cache.max.size")));
            }
            // 存储未识别的配置项
            for (String key : props.stringPropertyNames()) {
                if (!isRecognizedKey(key)) {
                    additionalConfig.put(key, props.getProperty(key));
                }
            }
            config.setAdditionalConfig(additionalConfig);
        } catch (IOException e) {
            throw new Exception("无法读取配置文件: " + filePath, e);
        }
        return config;
    }
    private boolean isRecognizedKey(String key) {
        String[] recognizedKeys = {
            "app.name", "app.version", "app.description",
            "db.host", "db.port", "db.username", "db.password", "db.database",
            "server.port", "server.host", "server.ssl.enabled",
            "cache.type", "cache.timeout", "cache.max.size"
        };
        return Arrays.asList(recognizedKeys).contains(key);
    }
    @Override
    public ConfigType getType() {
        return ConfigType.PROPERTIES;
    }
}

JSON解析器(使用Jackson)

package com.example.config.parser;
import com.example.config.model.AppConfig;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class JsonParser implements ConfigParser {
    private final ObjectMapper objectMapper;
    public JsonParser() {
        this.objectMapper = new ObjectMapper();
    }
    @Override
    public AppConfig parse(String filePath) throws Exception {
        AppConfig config = new AppConfig();
        Map<String, Object> additionalConfig = new HashMap<>();
        try {
            JsonNode rootNode = objectMapper.readTree(new File(filePath));
            // 解析应用配置
            JsonNode appNode = rootNode.get("app");
            if (appNode != null) {
                config.setAppName(getStringValue(appNode, "name"));
                config.setAppVersion(getStringValue(appNode, "version"));
                config.setAppDescription(getStringValue(appNode, "description"));
            }
            // 解析数据库配置
            JsonNode dbNode = rootNode.get("database");
            if (dbNode != null) {
                config.setDbHost(getStringValue(dbNode, "host"));
                config.setDbPort(getIntValue(dbNode, "port"));
                config.setDbUsername(getStringValue(dbNode, "username"));
                config.setDbPassword(getStringValue(dbNode, "password"));
                config.setDbDatabase(getStringValue(dbNode, "database"));
            }
            // 解析服务器配置
            JsonNode serverNode = rootNode.get("server");
            if (serverNode != null) {
                config.setServerPort(getIntValue(serverNode, "port"));
                config.setServerHost(getStringValue(serverNode, "host"));
                JsonNode sslNode = serverNode.get("ssl");
                if (sslNode != null) {
                    config.setSslEnabled(getBooleanValue(sslNode, "enabled"));
                }
            }
            // 解析缓存配置
            JsonNode cacheNode = rootNode.get("cache");
            if (cacheNode != null) {
                config.setCacheType(getStringValue(cacheNode, "type"));
                config.setCacheTimeout(getIntValue(cacheNode, "timeout"));
                config.setCacheMaxSize(getIntValue(cacheNode, "maxSize"));
            }
            // 存储未识别的配置项
            collectUnrecognizedConfig(rootNode, additionalConfig);
            config.setAdditionalConfig(additionalConfig);
        } catch (Exception e) {
            throw new Exception("无法解析JSON配置文件: " + filePath, e);
        }
        return config;
    }
    private String getStringValue(JsonNode node, String field) {
        JsonNode value = node.get(field);
        return value != null ? value.asText() : null;
    }
    private int getIntValue(JsonNode node, String field) {
        JsonNode value = node.get(field);
        return value != null ? value.asInt() : 0;
    }
    private boolean getBooleanValue(JsonNode node, String field) {
        JsonNode value = node.get(field);
        return value != null && value.asBoolean();
    }
    private void collectUnrecognizedConfig(JsonNode node, Map<String, Object> configMap) {
        Iterator<String> fieldNames = node.fieldNames();
        while (fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            if (!isRecognizedSection(fieldName)) {
                configMap.put(fieldName, node.get(fieldName).toString());
            }
        }
    }
    private boolean isRecognizedSection(String section) {
        return section.equals("app") || section.equals("database") || 
               section.equals("server") || section.equals("cache");
    }
    @Override
    public ConfigType getType() {
        return ConfigType.JSON;
    }
}

YAML解析器

package com.example.config.parser;
import com.example.config.model.AppConfig;
import org.yaml.snakeyaml.Yaml;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
public class YamlParser implements ConfigParser {
    private final Yaml yaml;
    public YamlParser() {
        this.yaml = new Yaml();
    }
    @Override
    @SuppressWarnings("unchecked")
    public AppConfig parse(String filePath) throws Exception {
        AppConfig config = new AppConfig();
        Map<String, Object> additionalConfig = new HashMap<>();
        try (FileInputStream input = new FileInputStream(filePath)) {
            Map<String, Object> rootConfig = yaml.load(input);
            // 解析应用配置
            Map<String, Object> appConfig = (Map<String, Object>) rootConfig.get("app");
            if (appConfig != null) {
                config.setAppName((String) appConfig.get("name"));
                config.setAppVersion((String) appConfig.get("version"));
                config.setAppDescription((String) appConfig.get("description"));
                // 移除已处理的键
                appConfig.remove("name");
                appConfig.remove("version");
                appConfig.remove("description");
                // 存储额外的app配置
                if (!appConfig.isEmpty()) {
                    additionalConfig.put("app_extra", appConfig);
                }
            }
            // 解析数据库配置
            Map<String, Object> dbConfig = (Map<String, Object>) rootConfig.get("database");
            if (dbConfig != null) {
                config.setDbHost((String) dbConfig.get("host"));
                config.setDbPort(getIntValue(dbConfig.get("port")));
                config.setDbUsername((String) dbConfig.get("username"));
                config.setDbPassword((String) dbConfig.get("password"));
                config.setDbDatabase((String) dbConfig.get("database"));
            }
            // 解析服务器配置
            Map<String, Object> serverConfig = (Map<String, Object>) rootConfig.get("server");
            if (serverConfig != null) {
                config.setServerPort(getIntValue(serverConfig.get("port")));
                config.setServerHost((String) serverConfig.get("host"));
                Map<String, Object> sslConfig = (Map<String, Object>) serverConfig.get("ssl");
                if (sslConfig != null) {
                    config.setSslEnabled((Boolean) sslConfig.get("enabled"));
                }
            }
            // 解析缓存配置
            Map<String, Object> cacheConfig = (Map<String, Object>) rootConfig.get("cache");
            if (cacheConfig != null) {
                config.setCacheType((String) cacheConfig.get("type"));
                config.setCacheTimeout(getIntValue(cacheConfig.get("timeout")));
                config.setCacheMaxSize(getIntValue(cacheConfig.get("maxSize")));
            }
            // 存储其他配置
            rootConfig.remove("app");
            rootConfig.remove("database");
            rootConfig.remove("server");
            rootConfig.remove("cache");
            if (!rootConfig.isEmpty()) {
                additionalConfig.put("other", rootConfig);
            }
            config.setAdditionalConfig(additionalConfig);
        } catch (Exception e) {
            throw new Exception("无法解析YAML配置文件: " + filePath, e);
        }
        return config;
    }
    private int getIntValue(Object value) {
        if (value instanceof Integer) {
            return (Integer) value;
        } else if (value instanceof String) {
            return Integer.parseInt((String) value);
        }
        return 0;
    }
    @Override
    public ConfigType getType() {
        return ConfigType.YAML;
    }
}

主程序入口

package com.example.config;
import com.example.config.model.AppConfig;
import com.example.config.parser.*;
public class Main {
    public static void main(String[] args) {
        // 获取配置文件路径
        String configDir = "src/main/resources/";
        // 1. 解析 Properties 文件
        System.out.println("=== Properties 配置文件解析 ===");
        try {
            PropertiesParser propertiesParser = new PropertiesParser();
            AppConfig propertiesConfig = propertiesParser.parse(configDir + "application.properties");
            System.out.println(propertiesConfig);
            System.out.println("额外配置: " + propertiesConfig.getAdditionalConfig());
        } catch (Exception e) {
            System.err.println("Properties解析失败: " + e.getMessage());
        }
        // 2. 解析 JSON 文件
        System.out.println("\n=== JSON 配置文件解析 ===");
        try {
            JsonParser jsonParser = new JsonParser();
            AppConfig jsonConfig = jsonParser.parse(configDir + "application.json");
            System.out.println(jsonConfig);
            System.out.println("额外配置: " + jsonConfig.getAdditionalConfig());
        } catch (Exception e) {
            System.err.println("JSON解析失败: " + e.getMessage());
        }
        // 3. 解析 YAML 文件
        System.out.println("\n=== YAML 配置文件解析 ===");
        try {
            YamlParser yamlParser = new YamlParser();
            AppConfig yamlConfig = yamlParser.parse(configDir + "application.yaml");
            System.out.println(yamlConfig);
            System.out.println("额外配置: " + yamlConfig.getAdditionalConfig());
        } catch (Exception e) {
            System.err.println("YAML解析失败: " + e.getMessage());
        }
        // 4. 使用工厂模式自动检测文件类型
        System.out.println("\n=== 自动检测解析器 ===");
        try {
            String[] configFiles = {
                configDir + "application.properties",
                configDir + "application.json",
                configDir + "application.yaml"
            };
            for (String configFile : configFiles) {
                AppConfig config = ConfigParserFactory.parse(configFile);
                System.out.println("解析 " + configFile + " 成功: " + config);
            }
        } catch (Exception e) {
            System.err.println("自动解析失败: " + e.getMessage());
        }
    }
}
// 配置解析器工厂(扩展)
class ConfigParserFactory {
    public static AppConfig parse(String filePath) throws Exception {
        ConfigParser parser = getParser(filePath);
        return parser.parse(filePath);
    }
    private static ConfigParser getParser(String filePath) throws Exception {
        if (filePath.endsWith(".properties")) {
            return new PropertiesParser();
        } else if (filePath.endsWith(".json")) {
            return new JsonParser();
        } else if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
            return new YamlParser();
        } else {
            throw new Exception("不支持的配置文件格式: " + filePath);
        }
    }
}

Maven依赖

<dependencies>
    <!-- JSON解析 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>
    <!-- YAML解析 -->
    <dependency>
        <groupId>org.yaml</groupId>
        <artifactId>snakeyaml</artifactId>
        <version>2.2</version>
    </dependency>
</dependencies>

运行结果示例

=== Properties 配置文件解析 ===
AppConfig{appName='ConfigDemo', appVersion='1.0.0', appDescription='配置文件解析示例', 
dbHost='localhost', dbPort=3306, dbUsername='root', serverPort=8080, serverHost='0.0.0.0', 
sslEnabled=false, cacheType='redis', cacheTimeout=3600, cacheMaxSize=1000}
额外配置: {}
=== JSON 配置文件解析 ===
AppConfig{appName='ConfigDemo', appVersion='1.0.0', appDescription='配置文件解析示例', 
dbHost='localhost', dbPort=3306, dbUsername='root', serverPort=8080, serverHost='0.0.0.0', 
sslEnabled=false, cacheType='redis', cacheTimeout=3600, cacheMaxSize=1000}
额外配置: {}
=== YAML 配置文件解析 ===
AppConfig{appName='ConfigDemo', appVersion='1.0.0', appDescription='配置文件解析示例', 
dbHost='localhost', dbPort=3306, dbUsername='root', serverPort=8080, serverHost='0.0.0.0', 
sslEnabled=false, cacheType='redis', cacheTimeout=3600, cacheMaxSize=1000}
额外配置: {}
=== 自动检测解析器 ===
解析 src/main/resources/application.properties 成功: ...
解析 src/main/resources/application.json 成功: ...
解析 src/main/resources/application.yaml 成功: ...

主要特点

  1. 支持多种格式: Properties、JSON、YAML
  2. 类型安全: 自动类型转换
  3. 错误处理: 完善的异常处理
  4. 可扩展性: 易于添加新的配置格式
  5. 额外配置: 支持非标准配置项的存储
  6. 工厂模式: 自动检测配置类型

这个案例展示了如何在Java中实现一个完整的配置文件解析系统,可以处理多种配置格式,并且易于扩展和维护。

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