前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java:学习commons-configuration2读取配置文件xml,properties

java:学习commons-configuration2读取配置文件xml,properties

作者头像
10km
发布2018-01-03 12:10:00
3K0
发布2018-01-03 12:10:00
举报
文章被收录于专栏:10km的专栏10km的专栏

commons-configuration是apache为java应用程序提供的一个通用的配置文件管理接口,可以支持多种配置文件格式:

Properties files XML documents Windows INI files Property list files (plist) JNDI JDBC Datasource System properties Applet parameters Servlet parameters

commons-configuration2是在已经广泛使用的commons-configuration 1.x版本基础上的一个升级版本,与1.x版本并不保持兼容。

刚开始使用commons-configuration2,这里做为笔记记录学习过程中的要点。

maven dependency

pom.xml 依赖配置如下,commons-beanutils,commons-jxpath对于commons-configuration2都是optional可选配件,但在本例都要用到所以必须加上否则运行会抛出异常 java.lang.ClassNotFoundException:

代码语言:javascript
复制
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-configuration2 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-configuration2</artifactId>
            <version>2.1.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-jxpath/commons-jxpath -->
        <dependency>
            <groupId>commons-jxpath</groupId>
            <artifactId>commons-jxpath</artifactId>
            <version>1.3</version>
        </dependency>

xml 表达式引擎

相比properties文件格式 xml要复杂多了(每个节点都可以有attribute),所以对于xml格式的配置文件,访问一个元素的值或attribute需要一套表达式规则来规定。比如路径节点用.分隔,attribute用@开头。commons-configuration提供了默认规则,但这个规则用户也是可以自定义的,也可以使用xpath标准。 下面的代码演示如何使用默认规则、xpath、自定义规则来访问Xml配置文件中的节点. 先贴出演示用的xml文件。 token.xml,放在源码根目录下,是一个很简单的配置文件,其中的description是节点属性。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <token>
        <device>
            <validate>true</validate>
        </device>
        <person>
            <validate>true</validate>
            <expire description="人员令牌失效时间(分钟) ">60</expire>
        </person>
    </token>
</configuration>

ConfigTest2.java

代码语言:javascript
复制
package net.gdface.facelog;

import org.apache.commons.configuration2.XMLConfiguration;
import org.apache.commons.configuration2.builder.fluent.Configurations;
import org.apache.commons.configuration2.tree.DefaultExpressionEngine;
import org.apache.commons.configuration2.tree.DefaultExpressionEngineSymbols;
import org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine;
import org.junit.Test;

public class ConfigTest2 {

    @Test
    public void test2() {
        try {
            Configurations configs = new Configurations();
            XMLConfiguration config = configs.xml(this.getClass().getClassLoader().getResource("token.xml"));
            {
                // 使用默认的符号定义创建一个表达式引擎
                DefaultExpressionEngine engine = new DefaultExpressionEngine(
                        DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS);
                // 指定表达式引擎
                config.setExpressionEngine(engine);
                System.out.println(config.getBoolean("token.device.validate"));
                System.out.println(config.getInt("token.person.expire"));
                System.out.println(config.getString("token.person.expire[@description]"));
            }
            {               
                // 使用 XPath表达式引擎
                // 请注意这里路径分隔符和attribute标签与上面使用DefaultExpressionEngine是不同的
                XPathExpressionEngine xpathEngine = new XPathExpressionEngine();
                config.setExpressionEngine(xpathEngine);
                System.out.println(config.getBoolean("token/device/validate"));
                System.out.println(config.getInt("token/person/expire"));
                System.out.println(config.getString("token/person/expire/@description"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

自定义表达式引擎

如果上面两种表达式引擎都不合你的意,比如不喜欢/@description[@description]这样的attribute标签(我就不喜欢)。你可以用自定义的符号规则生成一个DefaultExpressionEngine表达式引擎对象。 下面的演示就是如何用@做attribute的标签。 这部分的代码来自commons-configuration官网《Expression_engines》

代码语言:javascript
复制
    @Test
    public void test() {
        try
        {
            DefaultExpressionEngineSymbols symbols =
                    new DefaultExpressionEngineSymbols.Builder(
                        DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS)
                        // 指定属性分隔符或可以用xpath的概念叫路径分隔符
                        .setPropertyDelimiter(".")
                        // Indices should be specified in curly brackets
                        .setIndexStart("{")
                        .setIndexEnd("}")
                        // 指定@开头就是attribute标志
                        .setAttributeStart("@")
                        // attribute结尾符为null
                        .setAttributeEnd(null)
                        // A Backslash is used for escaping property delimiters
                        .setEscapedDelimiter("\\/")
                        .create();
            // 用自定义的符号DefaultExpressionEngineSymbols对象创建一个表达式引擎
            DefaultExpressionEngine engine = new DefaultExpressionEngine(symbols);
            Parameters params = new Parameters();
            FileBasedConfigurationBuilder<XMLConfiguration> builder =
                new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
                .configure(params.xml()
                    .setFileName("token.xml")
                    // 使用自定义的表达式引擎
                    .setExpressionEngine(engine));
            XMLConfiguration config = builder.getConfiguration();
            Configurations configs = new Configurations();
            XMLConfiguration config2 = configs.xml(this.getClass().getClassLoader().getResource("token.xml"));
            config2.setExpressionEngine(engine);
            System.out.println(config.getBoolean("token.device.validate"));
            System.out.println(config.getInt("token.person.expire"));
            System.out.println(config.getProperty("token.person.expire@description"));
        }
        catch(Throwable e)
        {
            e.printStackTrace();
        }
    }

properties文件编码

从properties中读取配置,如果不指定编码类型,是无法正常读取中文内容的。commons-configuration中通过FileBasedConfigurationBuilder.setDefaultEncoding方法来解决这个问题。示例如下:

代码语言:javascript
复制
    @Test
    public void test3(){
        try
        {
            Configurations configs = new Configurations();
            // setDefaultEncoding是个静态方法,用于设置指定类型(class)所有对象的编码方式。
            // 本例中是PropertiesConfiguration,要在PropertiesConfiguration实例创建之前调用。
            FileBasedConfigurationBuilder.setDefaultEncoding(PropertiesConfiguration.class, "UTF-8");
            PropertiesConfiguration propConfig = configs.properties(this.getClass().getClassLoader().getResource("log4j.properties"));
            System.out.println(propConfig.getString("log4j.appender.CONSOLE.Target"));
            System.out.println(propConfig.getBoolean("log4j.appender.LOGFILE.Append"));
            System.out.println(propConfig.getString("test"));
        }
        catch(Throwable e)
        {
            e.printStackTrace();
        }

配置文件中使用变量

commons-configuration是允许使用变量的.比如

java.home = ${env:JAVA_HOME} application.name = Killer App application.version = 1.6.2 application.title = ${application.name} ${application.version}

关于这部分的介绍看原文最好:《Variable_Interpolation》

多级配置文件

相当多的应用场景中,一些配置都有默认参数,同时又允许用户修改这些默认参数 ,所以一般会把包含默认参数的配置文件打在jar包中。而允许用户在外部用额外的用户配置文件(比如在user.home文件夹下放用户自定义配置文件)来覆盖默认参数,这就是Overriding properties。 当然用户也可以不提供这个自定义配置文件,全部使用默认参数,也就是说这个自定义配置文件是可选的,这就是Optional configuration sources。 下面的例子就应用了commons-configuration的这两个特性。 先定义一个root.xml,如下:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <properties fileName="${sys:user.home}/.facelog/config.properties" config-optional="true"/>
    <xml fileName="defaultConfig.xml" />
</configuration>

你可以把它当做一个配置文件的控制文件,它用来定义不同级别配置文件的优先级顺序,越往上面文件优先级越高可以覆盖下面文件中定义的变量。所以在最下面的就是默认配置文件,这就实现了Overriding properties。另外,除了最下面的默认配置文件外,上面的文件定义中都有指定config-optional="true"它的意思就是这个文件是可选的,如果该文件不存在也不会报错抛出异常。 在定义配置文件位置时用到的${sys:user.home}就是上一节提到的在配置文件中使用环境变量,${sys:user.home}指定使用JVM系统属性”user.home”(Linux下就是$HOME,Windows下就是%USERPROFILE%)来指定文件位置. 有了这个root.xml,就可以用Configurations.combined方法生成一个CombinedConfiguration对象,在${sys:user.home}下的config.properties定义的属性会覆盖defaultConfig.xml中的值。 调用方法如下

代码语言:javascript
复制
    @Test
    public void test4(){
        try
        {
            DefaultExpressionEngine engine = new DefaultExpressionEngine(DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS);
            Configurations configs = new Configurations();
            // 创建CombinedConfiguration 实例
            CombinedConfiguration config = configs.combined(this.getClass().getClassLoader().getResource("root.xml"));
            config.setExpressionEngine(engine);
            System.out.println(config.getBoolean("token.device.validate"));
            System.out.println(config.getInt("token.person.expire"));
            System.out.println(config.getString("token.person.expire[@description]"));

        }
        catch(Throwable e)
        {
            e.printStackTrace();
        }
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年11月21日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • maven dependency
  • xml 表达式引擎
    • 自定义表达式引擎
    • properties文件编码
    • 配置文件中使用变量
    • 多级配置文件
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档