引包
org.codehaus.castor
com.springsource.org.exolab.castor.xml
1.2.0
目标 XML文件
target.xml
java对象1的描述
1
java对象2的描述
10
配置Mapping需要的配置信息
config.xml
config.xml 的作用是:Mapping对象根据config.xml里的映射关系,将target.xml里解析出来的数据,通过反射注入对我们所需的对象。
案列所示,有三个层级关系,分别使用对象Plugin、Extension、Operation来表示
the Config of the Castor Mapping
所需对象
Plugin
@Getter
@Setter
public class Plugin implements Serializable {
private Long id;
private String name;
private String version;
private ArrayList extensions;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Plugin{");
sb.append("name='").append(name).append('\'');
sb.append(", version='").append(version).append('\'');
sb.append(", extensions=").append(extensions);
sb.append('}');
return sb.toString();
}
}
Extension
@Getter
@Setter
public class Extension {
private String id;
private String className;
private ArrayList operationGroup;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Extension{");
sb.append("id='").append(id).append('\'');
sb.append(", className='").append(className).append('\'');
sb.append(", operationGroup=").append(operationGroup);
sb.append('}');
return sb.toString();
}
}
Operation
@Getter
@Setter
public class Operation implements Serializable {
private String name;
private String desc;
private Integer index;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Operation{");
sb.append("name='").append(name).append('\'');
sb.append(", desc='").append(desc).append('\'');
sb.append(", index=").append(index);
sb.append('}');
return sb.toString();
}
}
XMLHelper
解析xml的方法定义在这里
@Slf4j
@Component
public class XMLHelper {
/**
* 加载Mapping的配置信息
*
* @param mappingPath mapping 文件的地址
* @return Mapping
*/
private Mapping loadMapping(String mappingPath) throws CustomException {
Mapping result;
if (StringUtil.isEmpty(mappingPath)) {
throw new CustomException("mappingPath is Empty...");
}
result = new Mapping();
String absolutePath = FileUtil.getFileAbsolutePath(mappingPath, "Mapping配置文件");
try {
result.loadMapping(absolutePath);
} catch (IOException e) {
log.error("文件不存在");
} catch (MappingException e) {
log.error("加载Mapping所需配置信息失败,(可能原因:xml文件中的配置项与java类不合)原因:" + e.getMessage(), e);
throw new CustomException("加载Mapping所需配置信息失败");
}
return result;
}
/**
* 解析xml文件
*
* @param xmlPath xml文件在工程里的相对路径
* @param mappingConfigPath 解析xml文件,储存Mapping对象需要的配置信息的辛苦xml文件的相对练路径
* @return Plugin对象
* @throws CustomException 系统自定义异常
*/
public Plugin parse(String xmlPath, String mappingConfigPath) throws CustomException {
if (StringUtil.isEmpty(xmlPath) || StringUtil.isEmpty(mappingConfigPath)) {
log.error(String.format("解析XML文件时,发现文件地址为空。" +
"xmlPath = [%s] , mappingConfigPath = [%s]", xmlPath, mappingConfigPath));
throw new CustomException("文件地址为空");
}
Mapping mapping = this.loadMapping(mappingConfigPath);
String xmlAbsolutePath = FileUtil.getFileAbsolutePath(xmlPath, "被解析的XML文件");
String encoding = getDeclaredFileEncoding(xmlAbsolutePath);
Unmarshaller unmarshaller = new Unmarshaller();
try {
unmarshaller.setMapping(mapping);
return parseByUnmarshaller(unmarshaller, xmlAbsolutePath, encoding);
} catch (Exception e) {
log.error("使用Unmarshaller解析XML失败,原因:" + e.getMessage(), e);
// 解决xml汉字乱码引起的xml解析失败的问题,用UTF-8重新解析一次
return parseByUnmarshaller(unmarshaller, xmlAbsolutePath, CharSetEnum.UTF8.value);
}
}
private Plugin parseByUnmarshaller(Unmarshaller unmarshaller, String xmlAbsolutePath, String encoding) throws CustomException {
Plugin result;
File target = new File(xmlAbsolutePath);
try (InputStream input = new FileInputStream(target);
Reader reader = new InputStreamReader(input, encoding)) {
result = (Plugin) unmarshaller.unmarshal(reader);
} catch (Exception e) {
log.error(String.format("解析xml[%s]失败,原因:%s", xmlAbsolutePath, e.getMessage()), e);
throw new CustomException("解析xml失败");
}
return result;
}
/**
* 获取xml文件的编码
*
* @param filePath 文件地址
* @return charSet eg:UTF-8
*/
private String getDeclaredFileEncoding(String filePath) {
String encoding = CharSetEnum.GBK.value;
if (!filePath.endsWith(".xml")) {
return encoding;
}
try (FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line = bufferedReader.readLine();
// 简单判断, 必须写在首行,且不换行
if (line.startsWith("") && line.toUpperCase().contains(CharSetEnum.UTF8.value)) {
encoding = CharSetEnum.UTF8.value;
}
} catch (IOException e) {
log.error("获取文件编码失败,原因:" + e.getMessage(), e);
}
return encoding;
}
}
调用XMLHelper的parse方法
@Slf4j
public class LoadXML {
public static void main(String[] args) throws CustomException {
XMLHelper xmlHelper = new XMLHelper();
String xmlPath = "castor/xml/target.xml";
String mappingConfigPath = "castor/mapping/config.xml";
Plugin result = xmlHelper.parse(xmlPath, mappingConfigPath);
log.info(result.toString());
}
}
输出结果
...LoadXML - Plugin{name='测试Castor解析', version='1.1', extensions=[Extension{id='extension', className='demo.zh.castor.dto.Extension', operationGroup=[Operation{name='java对象1', desc='java对象1的描述', index=1}, Operation{name='java对象2', desc='java对象2的描述', index=10}]}]}