本节摘要:本节主要介绍Castor插件的使用。
preparation
1.castor简介
castor是一种将java对象和XML自动绑定的开源软件。它可以在java对象、XML文本、SQL数据表以及LDAP目录之间绑定。Castor几乎是JAXB的替代品。Castor是ExoLab Group下面的一个开放源代码的项目,它主要实现的是O/R映射功能。它主要API和数据接口为:JDO-like, SQL, OQL, JDBC, LDAP, XML, DSML。它支持分布式目录事务处理和时间;提供处理XML、Directory、XADirectory的类库,提供从XML到JAVA类的转换机制。Castor(http://castor.exolab..org/)是一种将Java对象和XML自动绑定的开源软件。它可以在Java对象、XML文本、SQL数据表以及LDAP目录之间绑定。
2.下载需要用到的jar包
castor-1.0.1-xml.jar包下载地址:
http://www.castor.org/download.html
xercesImpl.jar包下载地址:
http://archive.apache.org/dist/xml/xerces-j/
也可以从下面的链接下载,以上两个jar包我都已经上传
http://files.cnblogs.com/java-pan/castor.rar
3.项目环境
system:win7 myeclipse:6.5 Tomcat:5.0 JDK:1.5 castor:1.0
项目结构图如下:
4.class&method
start
castor第一种用法:不使用xml配置文件
代码如下:
核心转换类--->DefaultCastor.java


1 package com.castor.def; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 import java.io.FileReader; 6 import java.io.FileWriter; 7 import java.io.IOException; 8 import java.io.Reader; 9 import java.io.Writer; 10 import org.exolab.castor.xml.MarshalException; 11 import org.exolab.castor.xml.Marshaller; 12 import org.exolab.castor.xml.Unmarshaller; 13 import org.exolab.castor.xml.ValidationException; 14 15 /** 16 * 17 *Module: DefaultCastor.java 18 *Description: 缺省的用法,无xml配置文件,javabean和XM的互转 19 *Company: 20 *Author: ptp 21 *Date: Apr 18, 2012 22 */ 23 public class DefaultCastor { 24 25 // getAbsolutePath();返回此抽象路径名的绝对路径名字符串 26 public static final String xmlPath = new File("").getAbsolutePath() 27 + "/src/com/castor/def/";; 28 29 /* 30 * 缺省用法:javabean转换为xml 31 * 缺省用法没有配置文件,即javabean和xml的映射文件 32 * 编组(marshalling) 33 */ 34 public static void defJavaBeanToXML() throws IOException, MarshalException, ValidationException{ 35 UserInfo userInfo = new UserInfo(); 36 userInfo.setUsername("张三"); 37 userInfo.setPassword("123456"); 38 File file = new File(xmlPath + "test.xml");//通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例 39 Writer writer = new FileWriter(file);// 根据给定的 File 对象构造一个 FileWriter对象 40 Marshaller marshaller = new Marshaller(writer); 41 marshaller.setEncoding("gbk");//设置xml的编码,默认的是UTF-8,显示的中文为乱码 42 marshaller.marshal(userInfo); 43 // Marshaller.marshal(userInfo, writer); 44 } 45 46 /* 47 * 缺省用法:xml转换为javabean 48 * 缺省用法没有配置文件,即javabean和xml的映射文件 49 * 解组(unmarshalling) 50 */ 51 public static void defXMLToJavaBean() throws FileNotFoundException, MarshalException, ValidationException{ 52 File file = new File(xmlPath + "test.xml"); 53 Reader reader = new FileReader(file);//在给定从中读取数据的 File 的情况下创建一个新 FileReader 54 UserInfo readUserInfo = (UserInfo) Unmarshaller.unmarshal(UserInfo.class,reader); 55 System.out.println("****************************************\n"); 56 System.out.println("username=" + readUserInfo.getUsername()+"\t password="+readUserInfo.getPassword()); 57 System.out.println("\n****************************************"); 58 59 } 60 public static void main(String[] args) throws IOException, 61 MarshalException, ValidationException { 62 //javabean--->xml 63 defJavaBeanToXML(); 64 //xml--->javabean 65 defXMLToJavaBean(); 66 67 } 68 69 }
使用的javabean--->UserInfo.java


1 package com.castor.def; 2 3 public class UserInfo { 4 5 public String username; 6 public String password; 7 public String getUsername() { 8 return username; 9 } 10 public void setUsername(String username) { 11 this.username = username; 12 } 13 public String getPassword() { 14 return password; 15 } 16 public void setPassword(String password) { 17 this.password = password; 18 } 19 }
测试效果:
运行DefaultCastor.java类中的main方法,在控制台以及/src/com/castor/def/目录下查看生成的XML文件
控制台:
生成的xml文件test.xml效果如图:
castor第二种用法:使用xml配置文件
代码如下:
javabean--->Book.java


1 package com.castor.mapping; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class Book { 7 8 private String isbn; 9 private String title; 10 private List<Author> authors; 11 12 public Book() { 13 } 14 15 public Book(String isbn, String title, List<Author> authors) { 16 this.isbn = isbn; 17 this.title = title; 18 this.authors = authors; 19 } 20 21 public Book(String isbn, String title, Author author) { 22 this.isbn = isbn; 23 this.title = title; 24 this.authors = new ArrayList<Author>(); 25 this.authors.add(author); 26 } 27 28 public void addAuthor(Author author) { 29 this.authors.add(author); 30 } 31 32 public List<Author> getAuthors() { 33 return authors; 34 } 35 36 public void setAuthors(List<Author> authors) { 37 this.authors = authors; 38 } 39 40 public String getIsbn() { 41 return isbn; 42 } 43 44 public void setIsbn(String isbn) { 45 this.isbn = isbn; 46 } 47 48 public String getTitle() { 49 return title; 50 } 51 52 public void setTitle(String title) { 53 this.title = title; 54 } 55 56 }
javabean--->Author.java


1 package com.castor.mapping; 2 3 public class Author { 4 5 private String firstName; 6 private String lastName; 7 8 public Author() { 9 } 10 11 public Author(String firstName, String lastName) { 12 super(); 13 this.firstName = firstName; 14 this.lastName = lastName; 15 } 16 17 public void setFirstName(String firstName) { 18 this.firstName = firstName; 19 } 20 21 public void setLastName(String lastName) { 22 this.lastName = lastName; 23 } 24 25 public String getFirstName() { 26 return firstName; 27 } 28 29 public String getLastName() { 30 return lastName; 31 } 32 }
配置文件--->book-mapping.xml


1 <?xml version="1.0"?> 2 <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" 3 "http://castor.org/mapping.dtd"> 4 5 <mapping> 6 <!-- 7 class标签指明需要映射的类 8 name是这个类的类名,需要指明类的全路径 9 Map-to只有根元素对应的类才配置这个属性,指定的值为XML的根元素的名称 10 Field 类字段和xml字段之间的映射 filed中的name是对应类中字段的属性名字 TYPE对应的是属性类型 11 Bind-xml 是xml文档中对应的字段信息,name、location是生成的XML元素的名称,可以任意指定,建议尽量取得有意义 12 node指明是element还是attribute,默认是element 13 --> 14 <class name="com.castor.mapping.Book"> 15 <map-to xml="book" /> 16 17 <field name="Title" type="java.lang.String"> 18 <bind-xml name="title" node="element" location="book-info" /> 19 </field> 20 <field name="Isbn" type="java.lang.String"> 21 <bind-xml name="isbn" node="element" location="book-info" /> 22 </field> 23 24 <field name="Authors" type="com.castor.mapping.Author" 25 collection="arraylist"> 26 <bind-xml name="author" /> 27 </field> 28 </class> 29 30 <class name="com.castor.mapping.Author"> 31 <field name="FirstName" type="java.lang.String"> 32 <bind-xml name="first" node="attribute" location="name" /> 33 </field> 34 35 <field name="LastName" type="java.lang.String"> 36 <bind-xml name="last" node="attribute" location="name" /> 37 </field> 38 </class> 39 40 </mapping> 41 42 <!-- 43 需要注意的是,一个映射文件可以映射多个类。并且Castor可以提供一个默认的mapping(如果你不想写这个文件的话, 44 但是一般对负责的结构,还是要写这样的mapping文件的), 45 在默认的映射中要遵守相应的命名规则,就是说java中studentName(驼峰表示法)映射到xml中的student-name。 46 -->
格式化相关类
读和写XML文件--->OperationFile.java


1 package com; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.FileNotFoundException; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.io.InputStream; 10 import java.io.InputStreamReader; 11 import java.io.OutputStream; 12 import java.io.UnsupportedEncodingException; 13 14 /** 15 *Module: OperationFile.java 16 *Description: 操作文件的工具类 17 *Company: 18 *Author: ptp 19 *Date: Feb 13, 2012 20 */ 21 public class OperationFile { 22 23 /** 24 * 读取文件中的内容 存在中文乱码问题 25 * @param path 26 * @return 27 * @throws IOException 28 */ 29 public static String readFile1(String path) throws IOException { 30 31 // 1.使用File类找到一个文件 32 File file = new File(path);// 声明File对象 33 34 // 2.通过子类实例化父类对象 35 InputStream in = null;// 准备好一个输入的对象 36 in = new FileInputStream(file);// 通过对象的多态性,进行实例化 37 38 // 3.进行读操作 39 byte b[] = new byte[(int) file.length()]; 40 int len = in.read(b); 41 42 // 4.关闭输出流 43 in.close(); 44 45 // 5.把byte数组转换为字符串 46 /* 47 * 通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String 48 * 参数: 49 bytes - 要解码为字符的 byte 数组 50 offset - 要解码的第一个 byte 的索引 51 length - 要解码的 byte 数 52 */ 53 String str = new String(b, 0, len); 54 return str; 55 } 56 57 /** 58 * 读文件,对于不知道文件大小采用的读取方式 59 * 解决了读出的文件中文乱码问题 60 * @param filePath 61 * @return 62 */ 63 public static String readFile2(String filePath) { 64 String fileContent = ""; 65 File file = new File(filePath); 66 if (file.isFile() && file.exists()) { 67 try { 68 InputStreamReader read = new InputStreamReader( 69 new FileInputStream(file), "GBK"); 70 BufferedReader reader = new BufferedReader(read); 71 String line; 72 try { 73 while ((line = reader.readLine()) != null) { 74 fileContent += line; 75 } 76 reader.close(); 77 read.close(); 78 } catch (IOException e) { 79 e.printStackTrace(); 80 } 81 82 } catch (UnsupportedEncodingException e) { 83 e.printStackTrace(); 84 } catch (FileNotFoundException e) { 85 e.printStackTrace(); 86 } 87 } 88 return fileContent; 89 } 90 91 /** 92 * 向文件中写入内容 93 * @param filepath 写入文件的文件路径 94 * @param write 写入的内容 95 * @param flag1 是否覆盖,true-不覆盖原来的内容(追加),false-覆盖原来的内容 96 * @param flag2 是否换行,true-换行后写入,false-直接在文件末尾写入 97 * @throws IOException 98 */ 99 public static void writeFile(String filepath, String str, boolean flag1, 100 boolean flag2) throws IOException { 101 102 // 1.使用File类找到一个文件 103 File file = new File(filepath); 104 105 // 2.通过子类实例化父类对象 106 OutputStream out = null;//准备好一个输出的对象 107 //flag1=true,追加;flag1=false,覆盖 108 out = new FileOutputStream(file, flag1);//实例化 109 110 // 3.以循环的方式输出 111 String result = ""; 112 if (flag1) { 113 if (flag2) { 114 result = "\n" + str; 115 } else { 116 result = str; 117 } 118 } else { 119 result = str; 120 } 121 122 byte b[] = result.getBytes(); 123 for (int i = 0; i < b.length; i++) { 124 out.write(b[i]); 125 } 126 out.close(); 127 } 128 129 public static void main(String args[]) throws IOException{ 130 String filepath="d:\\a.txt"; 131 String str="写入的字符串"; 132 writeFile(filepath,str,false,true); 133 } 134 135 }
格式化XML类--->FormatXML.java


1 package com.format; 2 3 import java.io.IOException; 4 import java.io.StringReader; 5 import java.io.StringWriter; 6 import java.io.Writer; 7 8 import org.apache.xml.serialize.OutputFormat; 9 import org.apache.xml.serialize.XMLSerializer; 10 11 import org.w3c.dom.Document; 12 import org.xml.sax.InputSource; 13 import org.xml.sax.SAXException; 14 15 import javax.xml.parsers.DocumentBuilder; 16 import javax.xml.parsers.DocumentBuilderFactory; 17 import javax.xml.parsers.ParserConfigurationException; 18 19 /** 20 * 21 * Module: FormatXML.java 22 * Description: 格式化xml 23 * Company: 24 * Author: ptp 25 * Date: Apr 7, 2012 26 */ 27 public class FormatXML { 28 29 private static Document parseXMLFile(String in) 30 throws ParserConfigurationException, SAXException, IOException { 31 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 32 DocumentBuilder db = dbf.newDocumentBuilder(); 33 InputSource is = new InputSource(new StringReader(in)); 34 return db.parse(is); 35 } 36 37 public static String formatXML(String unFormattedXml) 38 throws ParserConfigurationException, SAXException, IOException { 39 final Document document = parseXMLFile(unFormattedXml); 40 OutputFormat format = new OutputFormat(document); 41 format.setIndenting(true); 42 format.setLineWidth(65); 43 format.setIndent(2); 44 format.setEncoding("GBK"); 45 46 Writer out = new StringWriter(); 47 XMLSerializer serializer = new XMLSerializer(out, format); 48 serializer.serialize(document); 49 return out.toString(); 50 } 51 52 public static void main(String[] args) throws ParserConfigurationException, 53 SAXException, IOException { 54 String unFormattedXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><user_info><password>123456</password><username><a>张三</a><b>李四</b></username></user_info>"; 55 System.out.println("unFormattedXml:\n" + unFormattedXml); 56 String formattedXml = formatXML(unFormattedXml); 57 System.out.println("formattedXml:\n" + formattedXml); 58 } 59 60 }
测试类(java转xml)---BookMapMarshaller.java


1 package com.castor.mapping; 2 3 import java.io.File; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 import java.util.ArrayList; 7 import java.util.Iterator; 8 import java.util.List; 9 10 import javax.xml.parsers.ParserConfigurationException; 11 12 import org.exolab.castor.mapping.Mapping; 13 import org.exolab.castor.mapping.MappingException; 14 import org.exolab.castor.xml.MarshalException; 15 import org.exolab.castor.xml.Marshaller; 16 import org.exolab.castor.xml.ValidationException; 17 import org.xml.sax.SAXException; 18 19 import com.OperationFile; 20 import com.castor.mapping.Author; 21 import com.castor.mapping.Book; 22 import com.format.FormatXML; 23 24 public class BookMapMarshaller { 25 26 // 映射文件的路径 27 public static final String Mapping_XML = new File("").getAbsolutePath() 28 + "/src/com/castor/mapping/"; 29 // 解组后XML文件的路径 30 public static final String Result_XML = new File("").getAbsolutePath() 31 + "/src/com/castor/mapping/"; 32 33 /** 34 * 编组(marshalling) java转换为xml 35 * @throws MappingException 36 * @throws IOException 37 * @throws ValidationException 38 * @throws MarshalException 39 * @throws SAXException 40 * @throws ParserConfigurationException 41 */ 42 @SuppressWarnings("unchecked") 43 public static void main(String[] args) throws IOException, 44 MappingException, MarshalException, ValidationException, 45 ParserConfigurationException, SAXException { 46 //对对象设置值 47 List<Author> authors = new ArrayList<Author>(); 48 Book book = new Book(); 49 authors.add(new Author("三", "张")); 50 authors.add(new Author("四", "李")); 51 book.setAuthors(authors); 52 book.setIsbn("6921505081308"); 53 book.setTitle("thinking in java"); 54 55 Mapping mapping = new Mapping(); 56 //装载映射文件 57 mapping.loadMapping(Mapping_XML + "book-mapping.xml"); 58 59 //把解组后的文件输出到book-result.xml中 60 FileWriter writer = new FileWriter(Result_XML + "book-result.xml"); 61 Marshaller marshaller = new Marshaller(writer); 62 marshaller.setMapping(mapping); 63 marshaller.setEncoding("GBK");//解决中文乱码的问题 64 marshaller.marshal(book); 65 66 /* 67 * 格式化book-result.xml文件 68 */ 69 //1.读取book-result.xml文件 70 String unFormattedXml = OperationFile.readFile2(Result_XML 71 + "book-result.xml"); 72 //2.格式化XML文件 73 String formattedXml = FormatXML.formatXML(unFormattedXml); 74 //3.写入到book-result.xml文件 75 OperationFile.writeFile(Result_XML + "book-result.xml", formattedXml, 76 false, false); 77 78 //打印对象的信息 79 System.out.println("Book ISBN: " + book.getIsbn()); 80 System.out.println("Book Title: " + book.getTitle()); 81 authors = book.getAuthors(); 82 for (Iterator i = authors.iterator(); i.hasNext();) { 83 Author author = (Author) i.next(); 84 System.out.println("Author: " + author.getLastName() + " " 85 + author.getFirstName()); 86 } 87 } 88 }
测试效果:
运行BookMapMarshaller.java类中的main方法,在控制台以及/src/com/castor/def/目录下查看生成的XML文件
控制台:
生成的xml文件 book-result.xml效果如下:
result
note.txt文件是使用castor过程中遇到的一些文件以及相应的解决方法
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.exolab.castor.util.Configuration.<clinit>(Configuration.java:101) at org.exolab.castor.xml.Marshaller.initialize(Marshaller.java:379) at org.exolab.castor.xml.Marshaller.<init>(Marshaller.java:337) at com.castor.TestCastor.main(TestCastor.java:24) Exception in thread "main" 解决方案:导入commons-logging.jar包
java.lang.RuntimeException: Could not instantiate serializer org.apache.xml.serialize.XMLSerializer: java.lang.ClassNotFoundException: org.apache.xml.serialize.XMLSerializer at org.exolab.castor.xml.XercesSerializer.<init>(XercesSerializer.java:50) at org.exolab.castor.xml.XercesXMLSerializerFactory.getSerializer(XercesXMLSerializerFactory.java:31) at org.exolab.castor.util.LocalConfiguration.getSerializer(LocalConfiguration.java:531) at org.exolab.castor.xml.Marshaller.<init>(Marshaller.java:339) at com.castor.TestCastor.main(TestCastor.java:24) Exception in thread "main" 解决方案:有些地方说是JDK1.5以下因为没有集成XMLSerializer类,故会报这个错误,但是我改为JDK1.5还是报这个错误 正确的解决方法是导入xercesImpl.jar包,jar包的下载路径如下为:http://archive.apache.org/dist/xml/xerces-j/