使用commons-configuration2实现xml文件读取为对象

本文介绍了如何利用commons-configuration2库和Java反射机制,将XML文件转换为对应的JavaBean对象。传统的XML读取方法通常只能获取单一字段,而本文提供的方法能直接将整个XML映射到复杂的数据结构。通过引入相关依赖,定义匹配的JavaBean,并在main方法中执行转换操作,可以实现XML文件到Java对象的便捷转换。关键在于确保JavaBean的变量名与XML属性名一致。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近由于规范文件读写,所以需要实现对xml文件进行读取。
本文只是使用commons-configuration2包对xml文件读取。
目前网上介绍的大多都是简单的读取xml文件中的具体字段,甚至官方文档也是简单的进行了介绍。
如果需要直接将xml文件转换成javaBean则需要进行复杂的操作,或者是通过具体的javaBean内进行解析,才能实现。

通过网上搜集资料,发现commons-digester3,能够对javaBean解析。但是,每个对象的解析规则则要进行具体实现。
而本文,通过java的反射机制,实现了通过定义与xml文件对应的javaBean,进行直接转换。

1。首先导入依赖包。如果是maven管理则直接使用如下:

        <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-digester3</artifactId>
          <version>3.2</version>
          <classifier>with-deps</classifier>
        </dependency>

2.具体实现:



import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.configuration2.XMLConfiguration;
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters;
import org.nutz.json.Json;

/**
 * @author zongtao liu</br>
 *         2017年4月20日 下午4:37:29</br>
 */
public class XmlFileFactory {

    /***
     * 将文件加载为文件对应的对象
     * 
     * @param filePath
     * @param clazz
     * @return
     */
    public static <T> T loadFile(String filePath, Class<T> clazz) {
        T obj = null;
        Parameters params = new Parameters();
        FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<XMLConfiguration>(
                XMLConfiguration.class).configure(params.xml().setFileName(filePath));

        try {
            XMLConfiguration config = builder.getConfiguration();
            obj = loadObj(config, "", clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return obj;
    }

    /****
     * 加载对象
     * 
     * @param config
     * @param preProperty
     * @param clazz
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static <T> T loadObj(XMLConfiguration config, String preProperty, Class<T> clazz)
            throws InstantiationException, IllegalAccessException {
        T obj = clazz.newInstance();
        Field[] fields = clazz.getDeclaredFields();
        int num = 0;
        for (Field field : fields) {
            field.setAccessible(true); // 设置些属性是可以访问的
            String name = field.getName();
            String key = preProperty + name;
            Class<?> cls = field.getType();
            // 如果是枚举类型,直接跳过
            if (cls.isEnum()) {
                continue;
            }
            Object configValue = null;
            if (isBaseDataType(cls)) {// 如果是基础数据类型
                configValue = config.get(cls, key);
            } else if (cls.isArray()) {// 是否是数组
                Class<?> componentType = cls.getComponentType();
                if (isBaseDataType(componentType)) {
                    configValue = config.getArray(componentType, key);
                } else {
                    List list = new ArrayList();
                    int i = 0;
                    while (true) {
                        Object loadObj = loadObj(config,
                                key + "." + toLowerFirst(componentType.getSimpleName()) + "(" + i + ").",
                                componentType);
                        if (loadObj == null) {
                            break;
                        }
                        list.add(loadObj);
                        i++;
                    }
                    if (list.size() > 0) {
                        Object array = Array.newInstance(componentType, list.size());
                        for (int j = 0; j < list.size(); j++) {
                            Array.set(array, j, list.get(j));
                        }
                        configValue = array;
                    }
                }
            } else if (List.class.isAssignableFrom(cls)) {// 判断是否为list
                Type fc = field.getGenericType();
                if (fc == null) {
                    continue;
                }
                if (fc instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) fc;
                    Class<?> genericClazz = (Class<?>) pt.getActualTypeArguments()[0];
                    if (isBaseDataType(genericClazz)) {
                        configValue = config.getCollection(genericClazz, key, null);
                    } else {
                        List list = new ArrayList();
                        int i = 0;
                        while (true) {
                            Object loadObj = loadObj(config,
                                    key + "." + toLowerFirst(genericClazz.getSimpleName()) + "(" + i + ").",
                                    genericClazz);
                            if (loadObj == null) {
                                break;
                            }
                            list.add(loadObj);
                            i++;
                        }
                        configValue = list;
                    }
                }
            } else {// 其他则认为是对象
                configValue = loadObj(config, key + ".", cls);
            }
            if (configValue != null) {
                field.set(obj, configValue);
                num++;
            }
        }
        if (num == 0) {
            return null;
        }
        return obj;
    }

    /***
     * 首字母小写
     * 
     * @param str
     * @return
     */
    public static String toLowerFirst(String str) {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'A' && ch[0] <= 'Z') {
            ch[0] = (char) (ch[0] + 32);
        }
        return new String(ch);
    }

    /***
     * 判断是否是基础数据类型
     * 
     * @param clazz
     * @return
     */
    private static boolean isBaseDataType(Class clazz) {
        return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class)
                || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class)
                || clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class)
                || clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class)
                || clazz.isPrimitive());
    }

    public static void main(String[] args) {
        Config config = XmlFileFactory.loadFile("D:\\test.xml", Config.class);
        System.out.println(Json.toJson(config));

    }

}

3.xml文件内容

<?xml version="1.0" encoding="UTF-8"?>
<!-- springok1.xml -->
<config>
    <version>123456</version>
    <names>555555555</names>
    <names>666666666</names>
    <nameList>22222222222</nameList>
    <nameList>33333333333</nameList>
    <database>
        <url>127.0.0.1</url>
        <port>3306</port>
        <login>admin</login>
        <password></password>
    </database>
    <databases>
        <database>
        <url>127.0.1.1</url>
        <port>3306</port>
        <login>admin</login>
        <password></password>
    </database>
    <database>
        <url>127.0.1.2</url>
        <port>3306</port>
        <login>admin</login>
        <password></password>
    </database>
    </databases>
    <databaseArr>
        <database>
        <url>127.0.2.1</url>
        <port>3306</port>
        <login>admin</login>
        <password></password>
    </database>
    <database>
        <url>127.0.2.2</url>
        <port>3306</port>
        <login>admin</login>
        <password></password>
    </database>
    </databaseArr>
    <users>
        <user>
         <name>张三</name>
         <age>10</age>
         <info>admin1</info>
         <info>admin2</info>
        </user>
        <user>
         <name>李四</name>
         <age>10</age>
         <info>admin1</info>
         <info>admin2</info>
        </user>
    </users>
</config>

4.对应的javaBean
Config.java



import java.util.List;

/**
 * @author zongtao liu</br>
 *         2017年4月20日 下午6:35:38</br>
 */
public class Config {

    private int version;

    private String[] names;

    private List<String> nameList;

    private Database database;

    private Database[] databaseArr;

    private List<Database> databases;


    private List<User> users;

    /**
     * @return {@link #version}
     */
    public int getVersion() {
        return version;
    }

    /**
     * @param version {@linkplain #version 参见}
     */
    public void setVersion(int version) {
        this.version = version;
    }

    /**
     * @return {@link #names}
     */
    public String[] getNames() {
        return names;
    }

    /**
     * @param names {@linkplain #names 参见}
     */
    public void setNames(String[] names) {
        this.names = names;
    }

    /**
     * @return {@link #nameList}
     */
    public List<String> getNameList() {
        return nameList;
    }

    /**
     * @param nameList {@linkplain #nameList 参见}
     */
    public void setNameList(List<String> nameList) {
        this.nameList = nameList;
    }

    /**
     * @return {@link #database}
     */
    public Database getDatabase() {
        return database;
    }

    /**
     * @param database {@linkplain #database 参见}
     */
    public void setDatabase(Database database) {
        this.database = database;
    }

    /**
     * @return {@link #databaseArr}
     */
    public Database[] getDatabaseArr() {
        return databaseArr;
    }

    /**
     * @param databaseArr {@linkplain #databaseArr 参见}
     */
    public void setDatabaseArr(Database[] databaseArr) {
        this.databaseArr = databaseArr;
    }

    /**
     * @return {@link #databases}
     */
    public List<Database> getDatabases() {
        return databases;
    }

    /**
     * @param databases {@linkplain #databases 参见}
     */
    public void setDatabases(List<Database> databases) {
        this.databases = databases;
    }

    /**
     * @return {@link #users}
     */
    public List<User> getUsers() {
        return users;
    }

    /**
     * @param users {@linkplain #users 参见}
     */
    public void setUsers(List<User> users) {
        this.users = users;
    }

}

Database.java类

public class Database {
    private String url;

    private int port;

    private String login;

    private String password;

    /**
     * @return {@link #url}
     */
    public String getUrl() {
        return url;
    }

    /**
     * @param url
     *            {@linkplain #url 参见}
     */
    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * @return {@link #port}
     */
    public int getPort() {
        return port;
    }

    /**
     * @param port
     *            {@linkplain #port 参见}
     */
    public void setPort(int port) {
        this.port = port;
    }

    /**
     * @return {@link #login}
     */
    public String getLogin() {
        return login;
    }

    /**
     * @param login
     *            {@linkplain #login 参见}
     */
    public void setLogin(String login) {
        this.login = login;
    }

    /**
     * @return {@link #password}
     */
    public String getPassword() {
        return password;
    }

    /**
     * @param password
     *            {@linkplain #password 参见}
     */
    public void setPassword(String password) {
        this.password = password;
    }
}

User.java类

public class User {

    private String name;

    private int age;

    private String[] info;

    /**
     * @return {@link #name}
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            {@linkplain #name 参见}
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return {@link #age}
     */
    public int getAge() {
        return age;
    }

    /**
     * @param age
     *            {@linkplain #age 参见}
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * @return {@link #info}
     */
    public String[] getInfo() {
        return info;
    }

    /**
     * @param info
     *            {@linkplain #info 参见}
     */
    public void setInfo(String[] info) {
        this.info = info;
    }

}

5.运行工中的main方法,则直接可以将xml文件转成对应的javaBean。

注意:javaBaen的变量名称一定要和xml的属性名一直。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值