在项目需要从配置文件中读取一些数据,
yaml的作为一种可选的非XML方案已经宣告失败,
同事给我推荐了另外两个XML的解决方案:
Castor 或者Digester
Castor是一种将Java对象和XML自动绑定的开源软件. 它可以在Java对象,XML文本,SQL数据表以及LDAP目录之间绑定.
Digester原是Apache Jakarta Struts计划中的一部分,用来解析Web App中的XML配置文件,在开发一段时间之后,开发人员觉得这个小工具具有很普遍的使用场合,于是,将这个部分独立出来,放到Commons项目中。
由于Digester只是支持由XML到JavaBean的单向转换,而我的项目还需要能够从JavaBean到XML的转换。
所以我选择了Castor。
下面是Castor的例子
SearchField.java package org . scbit . lentinus . domain ;
import java.util.ArrayList ;
private List < Table > tables ;
this . tables = new ArrayList < Table >();
public List < Table > getTables () {
void addTable ( Table table ) {
Table.java package org . scbit . lentinus . domain ;
import java.util.ArrayList ;
private String tableDisplayName ;
private String tableClass ;
private List < Field > fields ;
this . fields = new ArrayList < Field >();
public List < Field > getFields () {
public void addField ( Field field ) {
public String getTableClass () {
public void setTableClass ( String tableClass ) {
this . tableClass = tableClass ;
public String getTableDisplayName () {
public void setTableDisplayName ( String tableDisplayName ) {
this . tableDisplayName = tableDisplayName ;
Field.java package org . scbit . lentinus . domain ;
private String fieldDisplay ;
private String fieldName ;
public String getFieldDisplay () {
public void setFieldDisplay ( String fieldDisplay ) {
this . fieldDisplay = fieldDisplay ;
public String getFieldName () {
public void setFieldName ( String fieldName ) {
this . fieldName = fieldName ;
转换代码
public void testField () throws Exception {
SearchField searchField = new SearchField ();
table . setTableDisplayName ( "级别信息" );
table . setTableClass ( "TbBasicInfor" );
field . setFieldDisplay ( "拉丁学名" );
field . setFieldName ( "latinName" );
field . setFieldDisplay ( "拉丁别名" );
field . setFieldName ( "latinAlias" );
searchField . addTable ( table );
"D:\\dev\\workplace\\eclipse_workspace\\LentinusEdodes\\WebRoot\\WEB-INF\\conf\\searchField.xml" );
Writer writer = new OutputStreamWriter ( new FileOutputStream ( file ),
Marshaller marshaller = new Marshaller ( writer );
marshaller . setEncoding ( "utf-8" ); // 关键
marshaller . marshal ( searchField );
// now restore the value and list what we get
Reader reader = new InputStreamReader ( new FileInputStream ( file ),
SearchField read = ( SearchField ) Unmarshaller . unmarshal (
SearchField . class , reader );
assertTrue ( read . getTables (). get ( 0 ). getTableDisplayName (). equals ( "级别信息" ));
转换后的XML文件
searchField.xml
<?xml version="1.0" encoding="utf-8"?>
<tables xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:type= "java:org.scbit.lentinus.domain.Table" >
<fields xsi:type= "java:org.scbit.lentinus.domain.Field" >
<field-display> 拉丁学名</field-display>
<field-name> latinName</field-name>
<fields xsi:type= "java:org.scbit.lentinus.domain.Field" >
<field-display> 拉丁别名</field-display>
<field-name> latinAlias</field-name>
<table-class> TbBasicInfor</table-class>
<table-display-name> 级别信息</table-display-name>
Castor使用起来还是比较简单的,但在读取中文的时候,要注意可能会有乱码问题,在它官方的FAQ中有相应的解释和解决方法。
> How do I set the encoding?
Create a new instance of the Marshaller class and use the setEncoding method. You’ll also need to make sure the encoding for the Writer is set properly as well:
…
String encoding = “ISO-8859-1”;
FileOutputStream fos = new FileOutputStream(“result.xml”);
OutputStreamWriter osw = new OuputStreamWriter(fos, encoding);
Marshaller marshaller = new Marshaller(osw);
marshaller.setEncoding(encoding);
…
参考文章
XML 与 Java 技术: 用 Castor 进行数据绑定
Castor JDO 入门
学习Digester笔记