使用commons-configuration2實現xml文件讀取爲對象

最近由於規範文件讀寫,所以需要實現對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的屬性名一直。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章