最近由于规范文件读写,所以需要实现对xml文件进行读取。
本文只是使用commons-configuration2包对xml文件读取。
目前网上介绍的大多都是简单的读取xml文件中的具体字段,甚至官方文档也是简单的进行了介绍。
如果需要直接将xml文件转换成javaBean则需要进行复杂的操作,或者是通过具体的javaBean内进行解析,才能实现。
通过网上搜集资料,发现commons-digester3,能够对javaBean解析。但是,每个对象的解析规则则要进行具体实现。
而本文,通过java的反射机制,实现了通过定义与xml文件对应的javaBean,进行直接转换。
1。首先导入依赖包。如果是maven管理则直接使用如下:
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-digester3artifactId>
<version>3.2version>
<classifier>with-depsclassifier>
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
* 2017年4月20日 下午4:37:29
*/
public class XmlFileFactory {
/***
* 将文件加载为文件对应的对象
*
* @param filePath
* @param clazz
* @return
*/
public static T loadFile(String filePath, Class clazz) {
T obj = null;
Parameters params = new Parameters();
FileBasedConfigurationBuilder builder = new FileBasedConfigurationBuilder(
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 loadObj(XMLConfiguration config, String preProperty, Class 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文件内容
<config>
<version>123456version>
<names>555555555names>
<names>666666666names>
<nameList>22222222222nameList>
<nameList>33333333333nameList>
<database>
<url>127.0.0.1url>
<port>3306port>
<login>adminlogin>
<password>password>
database>
<databases>
<database>
<url>127.0.1.1url>
<port>3306port>
<login>adminlogin>
<password>password>
database>
<database>
<url>127.0.1.2url>
<port>3306port>
<login>adminlogin>
<password>password>
database>
databases>
<databaseArr>
<database>
<url>127.0.2.1url>
<port>3306port>
<login>adminlogin>
<password>password>
database>
<database>
<url>127.0.2.2url>
<port>3306port>
<login>adminlogin>
<password>password>
database>
databaseArr>
<users>
<user>
<name>张三name>
<age>10age>
<info>admin1info>
<info>admin2info>
user>
<user>
<name>李四name>
<age>10age>
<info>admin1info>
<info>admin2info>
user>
users>
config>
4.对应的javaBean
Config.java
import java.util.List;
/**
* @author zongtao liu
* 2017年4月20日 下午6:35:38
*/
public class Config {
private int version;
private String[] names;
private List nameList;
private Database database;
private Database[] databaseArr;
private List databases;
private List 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 getNameList() {
return nameList;
}
/**
* @param nameList {@linkplain #nameList 参见}
*/
public void setNameList(List 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 getDatabases() {
return databases;
}
/**
* @param databases {@linkplain #databases 参见}
*/
public void setDatabases(List databases) {
this.databases = databases;
}
/**
* @return {@link #users}
*/
public List getUsers() {
return users;
}
/**
* @param users {@linkplain #users 参见}
*/
public void setUsers(List 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的属性名一直。