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