 | Level: Advanced Brett D. McLaughlin, Sr. (brett@newInstance.com), Author and Editor, O'Reilly Media, Inc.
10 Dec 2007 In the last article of this series, you downloaded, installed, and set up
Castor. In this article, you'll learn how to convert your Java™ classes to XML and
transform that XML back into Java code, as well as how Castor works and how to design
your classes to function well with the API.
What you should already have
Before you go any further, you should ensure you have the prerequisites for this
article. The simplest way to take care of these requirements is to follow the steps
outlined in the first article in this series (links are in the ever-present Resources of the article). That first article walks you through downloading Castor, installing and configuring it, and testing the API on some very simple classes.
You also would do well to have some classes you'd like to convert to and from XML from
a project you're working on. There are sample classes provided with this (and the
previous) article, but your own mastery of Castor is best achieved if you apply what you see here to your own projects. Start with some basic object classes, representing a person, a CD, a book, or some other concrete object. Then, when you get into the mapping section of this article, you can add in more complexity.
Marshalling 101
The most basic operation in Castor is to take a Java class and marshal an
instance of that class to XML. You take the class itself and use it as a top-level container element. So a Book class would most likely result in an XML document with a root element called "book."
Each individual property of that class is then represented in the XML document. So a title property with a value of "Power Play" would generate XML like this:
<title>Power Play</title> |
It's fairly easy to extrapolate out from this the rest of an XML document based on a simple Java class.
You marshal instances of a class
A few notes before you start to marshall code. First, you always marshal an instance of a class, not the class itself. A class is structure, and is best equated to an XML constraint model, like a DTD or XML Schema. A class on its own has no data, and merely defines the structure for data to be stored, as well as how it can be accessed.
You instantiate (or obtain from a factory or other instance-producing mechanism) that class to give it a specific form. Then, you populate the fields of that instance with actual data. That instance is unique; it bears the same structure as any other instances of the same class, but the data is separate. Figure 1 illustrates this idea visually.
Figure 1. Classes provide structure, instances are the data
So your will marshall your instances. In a later section, you'll examine how to change
the structure of your XML using a constraint model and mapping files. For now, though,
you'll try to match the XML structure (elements and attributes) to the Java structure (properties).
Basic marshalling
Listing 1 is a simple Book class you'll use in this article.
Listing 1. A Book class
package ibm.xml.castor;
public class Book {
/** The book's ISBN */
private String isbn;
/** The book's title */
private String title;
/** The author's name */
private String authorName;
public Book(String isbn, String title, String authorName) {
this.isbn = isbn;
this.title = title;
this.authorName = authorName;
}
public String getIsbn() {
return isbn;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public String getAuthorName() {
return authorName;
}
}
|
Compile this code, and you'll have a Book.class file. The class is extremely simple, with 3 properties: ISBN, title, and author name (there are some problems with this, but hold that thought for now). Castor needs little more than this file and a few lines of code to convert an instance of the Book class into an XML document. Listing 2 is a simple program that creates a new instance of Book and writes it out to XML using Castor.
Listing 2. A Book marshaller class
package ibm.xml.castor;
import java.io.FileWriter;
import org.exolab.castor.xml.Marshaller;
public class BookMarshaller {
public static void main(String[] args) {
try {
Book book = new Book("9780312347482", "Power Play", "Joseph Finder");
FileWriter writer = new FileWriter("book.xml");
Marshaller.marshal(book, writer);
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace(System.err);
}
}
}
|
Compile and run this program. You'll see a new file created, book.xml. Open that file, and you should see something like this:
Listing 3. XML created by
compiled program
<?xml version="1.0" encoding="UTF-8"?>
<book><author-name>Joseph Finder</author-name>
<isbn>9780312347482</isbn><title>Power Play</title></book> |
I added the line break here for printing on the screen. The actual generated XML
document has no line break between the closing tag of the author-name element and the opening isbn element.
What Castor leaves out
Before you refine this example—and it does need some refinement—take a moment and notice what Castor does not preserve in the XML:
-
The package of the Java class. A Java package is not part of a class's
structure. It's actually a semantic issue, related to Java namespaces. So you could
unmarshall—convert from XML to Java code—this XML document to any
Book instance that had the same three properties, regardless of package.
-
Field ordering. Order matters in XML, but not in Java programming. So even though the source file listed the fields in one order, the XML document used another. That's important in your XML, but irrelevant in your
Book class declaration.
-
Methods. Methods, like a package declaration, have nothing to do with data structuring. So the XML document doesn't do anything with them; they're ignored.
This is the big "So what?" moment, right? Who cares if the XML loses these little details, if they're not important? But they are important. They're important in that they give you more flexibility than you might expect. You can take this XML and unmarshall it into any class that meets a bare minimum of requirements:
- The class is named "Book" (something you can get around with a mapping file, but that's for later).
- The class has fields called
authorName, title, and isbn.
That's it! See if you can write several classes that meet these requirements, while
varying the other fields that the class might have, or the package declaration, or the methods . . . you'll quickly see how flexible this makes Castor.
Adding more complex types
The most glaring deficiency in the Book class is its
inability to store more than one author. Changing the class to handle multiple authors
is easy:
Listing 4. Book class that
stores multiple authors
package ibm.xml.castor;
import java.util.LinkedList;
import java.util.List;
public class Book {
/** The book's ISBN */
private String isbn;
/** The book's title */
private String title;
/** The authors' names */
private List authorNames;
public Book(String isbn, String title, List authorNames) {
this.isbn = isbn;
this.title = title;
this.authorNames = authorNames;
}
public Book(String isbn, String title, String authorName) {
this.isbn = isbn;
this.title = title;
this.authorNames = new LinkedList();
authorNames.add(authorName);
}
public String getIsbn() {
return isbn;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setAuthorNames(List authorNames) {
this.authorNames = authorNames;
}
public List getAuthorNames() {
return authorNames;
}
public void addAuthorName(String authorName) {
authorNames.add(authorName);
}
} |
If you use Java 5 or 6 technology, you'll get some unchecked/unsafe operation errors, because this code doesn't use parameterized Lists. You can add that code in yourself if you like.
This is a simple change, and doesn't require any modification to your marshalling code. However, it's worth using a book with multiple authors to see how the Castor marshalling process handles collections. Make the noted changes below to your BookMarshaller class:
Listing 5. Book class that
handles collectors
package ibm.xml.castor;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import org.exolab.castor.xml.Marshaller;
public class BookMarshaller {
public static void main(String[] args) {
try {
Book book = new Book("9780312347482", "Power Play", "Joseph Finder");
FileWriter writer = new FileWriter("book.xml");
Marshaller.marshal(book, writer);
List book2Authors = new ArrayList();
book2Authors.add("Douglas Preston");
book2Authors.add("Lincoln Child");
Book book2 = new Book("9780446618502", "The Book of the Dead",
book2Authors);
writer = new FileWriter("book2.xml");
Marshaller.marshal(book2, writer);
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace(System.err);
}
}
} |
The first book is handled the same way; you can re-open book.xml, and you'll see the same output as before. You can also open up book2.xml and see how Castor handled collections:
Listing 6. XML results
with collectors
<?xml version="1.0" encoding="UTF-8"?>
<book><isbn>9780446618502</isbn><title>The Book of the Dead</title>
<author-names xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="java:java.lang.String">Douglas Preston</author-names>
<author-names xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="java:java.lang.String">Lincoln Child</author-names>
</book> |
Obviously, Castor had no problem dealing with the list of author names. More
importantly, Castor did more than create a blanket container for the author names; the
framework actually looked inside the list, and realized that the contents were
strings (remember, this is not a parameterized list, so Castor bore the burden of
getting the type of each member of the list). So you get some pretty specific typing in
the XML. That's a nice feature, especially if you process the XML before it goes back
into Java code.
Adding custom classes
Let's take things another step towards a realistic application. Storing String author
names is a sure way to end up with duplicate data (most authors do write more than one
book). Listing 7 adds a new class, Author, into the mix.
Listing 7. An Author class
package ibm.xml.castor;
public class Author {
private String firstName, lastName;
private int totalSales;
public Author(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setTotalSales(int totalSales) {
this.totalSales = totalSales;
}
public void addToSales(int additionalSales) {
this.totalSales += additionalSales;
}
public int getTotalSales() {
return totalSales;
}
} |
Simple enough, right? Make the changes below to your Book class to use this new Author class.
Listing 8. Book class that
uses custom author class
package ibm.xml.castor;
import java.util.LinkedList;
import java.util.List;
public class Book {
/** The book's ISBN */
private String isbn;
/** The book's title */
private String title;
/** The authors' names */
private List authors;
public Book(String isbn, String title, List authors) {
this.isbn = isbn;
this.title = title;
this.authors = authors;
}
public Book(String isbn, String title, Author author) {
this.isbn = isbn;
this.title = title;
this.authors = new LinkedList();
authors.add(author);
}
public String getIsbn() {
return isbn;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setAuthors(List authors) {
this.authors = authors;
}
public List getAuthors() {
return authors;
}
public void addAuthor(Author author) {
authors.add(author);
}
} |
You'll need to make some more small tweaks to BookMarshaller to exercise this code:
Listing 9. BookMarshaller
class with added author information
package ibm.xml.castor;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import org.exolab.castor.xml.Marshaller;
public class BookMarshaller {
public static void main(String[] args) {
try {
Author finder = new Author("Joseph", "Finder");
Book book = new Book("9780312347482", "Power Play", finder);
FileWriter writer = new FileWriter("book.xml");
Marshaller.marshal(book, writer);
List book2Authors = new ArrayList();
book2Authors.add(new Author("Douglas", "Preston"));
book2Authors.add(new Author("Lincoln", "Child"));
Book book2 = new Book("9780446618502", "The Book of the Dead",
book2Authors);
writer = new FileWriter("book2.xml");
Marshaller.marshal(book2, writer);
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace(System.err);
}
}
} |
That's it! Compile everything and run the marshaller. Check out both files; only book2.xml is shown here, since it's a little more interesting.
Listing 10. XML results
with authors and books
<?xml version="1.0" encoding="UTF-8"?>
<book><authors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
total-sales="0" xsi:type="java:ibm.xml.castor.Author"><last-name>Preston</last-name>
<first-name>Douglas</first-name></authors><authors
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" total-sales="0"
xsi:type="java:ibm.xml.castor.Author"><last-name>Child</last-name>
<first-name>Lincoln</first-name></authors><isbn>9780446618502</isbn>
<title>The Book of the Dead</title></book>
|
Once again, Castor had no trouble. It figured out how to marshal not only the Book class, but the Author class as well (again, but introspecting the authors list). Castor even threw in the totalSales property of Author, so you could set that and see it show up in the XML as well.
Castor does generics
Yes, it's starting to sounds like an all-night sales channel, but Castor can handle generics and parameterized Lists. So if you're of a Java 5 or Java 6 mind, you can change Book like so:
Listing 11. Book class to
handle generics and parameterized lists
package ibm.xml.castor;
import java.util.LinkedList;
import java.util.List;
public class Book {
/** The book's ISBN */
private String isbn;
/** The book's title */
private String title;
/** The authors' names */
private List<Author> authors;
public Book(String isbn, String title, List<Author> authors) {
this.isbn = isbn;
this.title = title;
this.authors = authors;
}
public Book(String isbn, String title, Author author) {
this.isbn = isbn;
this.title = title;
this.authors = new LinkedList<Author>();
authors.add(author);
}
public String getIsbn() {
return isbn;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setAuthors(List<Author> authors) {
this.authors = authors;
}
public List<Author> getAuthors() {
return authors;
}
public void addAuthor(Author author) {
authors.add(author);
}
} |
Now, your author list only accepts Author instances, which is a pretty major improvement. You can make similar changes to BookMarshaller, re-compile, and you'll get the same XML output. In other words, you can build pretty solid classes for use with Castor.
Your classes change, Castor doesn't
Before finally moving on to unmarshalling, a remarkable observation should be made. In all the tweaking and changing of classes over the last sections, you never had to change your marshalling code! You added generics, a custom class, collections . . . throughout, though, the Castor API allowed a single simple call for marshalling to XML. Pretty impressive!
Unmarshalling
After all the time and detail spent on marshalling, unmarshalling is pretty simple. You
take an XML document, ensure you have a Java class that matches the data, and let Castor
do the work. Let's unmarshall the two XML documents we generated earlier. Listing 12 takes care of the work.
Listing 12. Unmarshalling books
package ibm.xml.castor;
import java.io.FileReader;
import java.util.Iterator;
import java.util.List;
import org.exolab.castor.xml.Unmarshaller;
public class BookUnmarshaller {
public static void main(String[] args) {
try {
FileReader reader = new FileReader("book.xml");
Book book = (Book)Unmarshaller.unmarshal(Book.class, reader);
System.out.println("Book ISBN: " + book.getIsbn());
System.out.println("Book Title: " + book.getTitle());
List authors = book.getAuthors();
for (Iterator i = authors.iterator(); i.hasNext(); ) {
Author author = (Author)i.next();
System.out.println("Author: " + author.getFirstName() + " " +
author.getLastName());
}
System.out.println();
reader = new FileReader("book2.xml");
book = (Book)Unmarshaller.unmarshal(Book.class, reader);
System.out.println("Book ISBN: " + book.getIsbn());
System.out.println("Book Title: " + book.getTitle());
authors = book.getAuthors();
for (Iterator i = authors.iterator(); i.hasNext(); ) {
Author author = (Author)i.next();
System.out.println("Author: " + author.getFirstName() + " " +
author.getLastName());
}
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace(System.err);
}
}
} |
Compile this code and run it. You'll probably get an unexpected result! My error and my stack trace are shown here:
Listing 13. Unmarshalling
error and stack trace
[bmclaugh:~/Documents/developerworks/castor-2]
java ibm.xml.castor.BookUnmarshaller
ibm.xml.castor.Book
org.exolab.castor.xml.MarshalException: ibm.xml.castor.Book{File:
[not available]; line: 2; column: 7}
at org.exolab.castor.xml.Unmarshaller.
convertSAXExceptionToMarshalException(Unmarshaller.java:755)
at org.exolab.castor.xml.Unmarshaller.unmarshal
(Unmarshaller.java:721)
at org.exolab.castor.xml.Unmarshaller.unmarshal
(Unmarshaller.java:610)
at org.exolab.castor.xml.Unmarshaller.unmarshal
(Unmarshaller.java:812)
at ibm.xml.castor.BookUnmarshaller.main
(BookUnmarshaller.java:14)
Caused by: java.lang.InstantiationException: ibm.xml.castor.Book
at java.lang.Class.newInstance0(Class.java:335)
at java.lang.Class.newInstance(Class.java:303)
at org.exolab.castor.util.DefaultObjectFactory.createInstance(
DefaultObjectFactory.java:107)
at org.exolab.castor.xml.UnmarshalHandler.createInstance(
UnmarshalHandler.java:2489)
at org.exolab.castor.xml.UnmarshalHandler.startElement(
UnmarshalHandler.java:1622)
at org.exolab.castor.xml.UnmarshalHandler.startElement(
UnmarshalHandler.java:1353)
at org.apache.xerces.parsers.AbstractSAXParser.startElement
(Unknown Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.startElement
(Unknown Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanStartElement(
Unknown Source)
at org.apache.xerces.impl.XMLDocumentScannerImpl
$ContentDispatcher.
scanRootElementHook(Unknown Source)
at org.apache.xerces.impl.
XMLDocumentFragmentScannerImpl
$FragmentContentDispatcher.dispatch(
Unknown Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(
Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse
(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse
(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown
Source)
at org.exolab.castor.xml.Unmarshaller.unmarshal
(Unmarshaller.java:709)
... 3 more
Caused by: java.lang.InstantiationException: ibm.xml.castor.Book
at java.lang.Class.newInstance0(Class.java:335)
at java.lang.Class.newInstance(Class.java:303)
at org.exolab.castor.util.DefaultObjectFactory.createInstance(
DefaultObjectFactory.java:107)
at org.exolab.castor.xml.UnmarshalHandler.createInstance(
UnmarshalHandler.java:2489)
at org.exolab.castor.xml.UnmarshalHandler.startElement
(UnmarshalHandler.java:1622)
at org.exolab.castor.xml.UnmarshalHandler.startElement
(UnmarshalHandler.java:1353)
at org.apache.xerces.parsers.AbstractSAXParser.startElement
(Unknown Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.startElement
(Unknown Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanStartElement(
Unknown Source)
at org.apache.xerces.impl.XMLDocumentScannerImpl
$ContentDispatcher.
scanRootElementHook(Unknown Source)
at org.apache.xerces.impl.
XMLDocumentFragmentScannerImpl
$FragmentContentDispatcher.dispatch(
Unknown Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(
Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse
(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse
(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown
Source)
at org.exolab.castor.xml.Unmarshaller.unmarshal
(Unmarshaller.java:709)
at org.exolab.castor.xml.Unmarshaller.unmarshal
(Unmarshaller.java:610)
at org.exolab.castor.xml.Unmarshaller.unmarshal
(Unmarshaller.java:812)
at ibm.xml.castor.BookUnmarshaller.main
(BookUnmarshaller.java:14) |
So what's going on? Well, you're run into the first of several concessions you'll have to make in order to use Castor out-of-the-box for data binding.
Castor requires no-args constructors
Castor handles unmarshalling largely through reflection and calls like Class.forName(your class name here).newInstance(). This makes it possible for Castor to instantiate your classes without knowing much about them. However, it also requires that the class be instantiable through a no-argument constructor.
The good news is that a simple change to your Book and Author classes will take care of this error. Just add no-args constructors to both (public Book() { } and public Author() { }). Recompile, and run your code again.
Consider the implications of this. A no-args constructor allows not just Castor, but any class or program to create new instances of your classes. In the case of books and authors, you can create books without ISBNs, titles, and authors, and authors without first or last names—a definite problem. There's no way to work around this without getting into some more advanced Castor features (which we'll do in the next article), so you're going to have to be very careful about how your classes are used. You should also consider setting any data types that could result in NullPointerExceptions to a real value (strings should be set to an empty string or default value, objects should be initialized, etc.).
Take two: More null issues
With your Book and Author classes, sporting no-arg constructors, re-run the test unmarshaller. You'll get output like this:
Listing 14. Unmarshalling
results with no-arg constructors
[bmclaugh:~/Documents/developerworks/castor-2] java ibm.xml.castor.BookUnmarshaller
Book ISBN: null
Book Title: Power Play
Author: null null
Book ISBN: null
Book Title: The Book of the Dead
Author: null null
Author: null null |
Looks like there are still some problems to deal with (Unmarshalling was supposed to be
simple right? Hold that thought, I'll talk about that more in a moment). Notably, several fields are null. Compare these fields to the XML, and you'll see that the fields are correctly represented in the XML document. So what gives?
To get a bead on what's going on, notice that the title of the book did get set
correctly. Additionally, take a close look at the second book, titled The Book of the
Dead. While it may appear at first glance that the authors for both books didn't
get set, that's not the case. In fact, this second book correctly has two references to Author objects. So it refers to both objects; however, the objects themselves don't have first and last name values set. So the title of a book gets set, as do the authors. However, the ISBN is null, and the first and last names of the authors are null. Here's another hint: if you displayed the total sales for an author, those values would not be null.
Figure it out? The null-valued fields all have no setter (or mutator) methods. There's no setIsbn(), no setFirstName(), etc. That's because the classes were designed to require that information in construction (once a book has its ISBN set, the ISBN really shouldn't be changeable; that in essence means a new book is created, so it's better to require construction/instantiation of a new book with the new ISBN).
Castor uses reflection, though, remember? And just as it can't create an object unless that object has a no-args constructor, it can't set the value of a field without a setFieldName() method. So you need to add those methods in to your Book and Author classes. Here are the methods you should add to your classes (the implementation is trivial, and left for you):
-
setIsbn(String isbn) (in the Book class)
-
setFirstName(String firstName) (in the Author class)
-
setLastName(String lastName) (in the Author class)
Add these methods in, re-compile, and you're ready to go.
Take three: Successful unmarshalling
Try to and run your unmarshaller again, and you should get output like this:
Listing 15. Unmarshalling
results with author and ISBNsetter methods
[bmclaugh:~/Documents/developerworks/castor-2] java ibm.xml.castor.BookUnmarshaller
Book ISBN: 9780312347482
Book Title: Power Play
Author: Joseph Finder
Book ISBN: 9780446618502
Book Title: The Book of the Dead
Author: Douglas Preston
Author: Lincoln Child |
Finally, this is what you wanted to see. You had to make several changes to your
classes. But remember earlier, I said that unmarshalling was terribly simple. Does that
match up with what you've see? With all the changes you made to your classes to get unmarshalling to work?
In fact, it does. The changes you made were in your classes, not in the Castor unmarshalling process. Castor is very simple to use, as long as your classes are constructed in the way Castor expects them to be—each class having a no-arg constructor and get/set methods for each field.
Worth the price
The classes you have now are not far cries from what you began with. Book and Author are not unrecognizable, and they're not vastly different (actually, they're not at all different) in functionality. However, the design is now a bit questionable. A book must have an ISBN (in my world, at least), so the ability to create a new book without one—that no-arg constructor—bothers me quite a bit. Additionally, I don't like that someone could come along and change a book's ISBN; that's not a correct representation of what the object is.
The changes to authors are less onerous, because names probably aren't great
identifiers for the object. Last names can change, and even first names these days.
Additionally, two authors might have identical names with no current way to distinguish
between them. But even if you did add a more unique and appropriate identifier (social security number, driver's license number, some arbitrary identifier), you'll still need a no-args constructor and setter for that field. So the problems remain.
The question becomes one of value and control:
- Does Castor provide enough value—by allowing simple data binding—to be worth the design concessions you have to make?
- Do you have enough control over your code base to build in protections against misuse of the methods you've added to function with Castor?
Only you can answer these questions for your organization. For most developers, the
tradeoffs come out in favor of Castor, and you'll make the concessions. For the few of
you mired enough in design and specific application requirements to make these
concessions untenable, you're probably comfortable creating your own simple XML serialization. Either way, you should have Castor in your tool belt. If it's not suitable for your current project, it probably will be for an upcoming one.
What's next?
The big missing ingredient in Castor so far is mapping files. You dealt with
translating directly from Java code to XML in detail. But that assumes several things:
- You want every field in your Java class persisted into XML.
- You want to preserve the names of your classes and fields in the XML.
- You have a class model that matches the data in XML documents you must de-serialize.
None of these are very safe assumptions in enterprise programming. What if storing your
field and class names in an XML document is seen as a security risk, revealing too much
of your application structure? What if someone else gives you an XML document, you want
to convert it to Java code, but you want to use different method names or field names? What if you only want a few of your class's attributes stored in XML?
For all of these questions, the answer is the same: Castor provides a way to take
greater control over the mapping from Java code to XML and back. In the next article,
you'll dig deep into mapping. For now, spend some time not only marshalling and
unmarshalling, but really thinking through the implications of the design changes you
have to make for Castor to behave like it should. And while you think, check back often
for the next article. Until then, see you online.
Downloads | Description | Name | Size | Download method |
|---|
| Java source code from this article | x-xjavacastor2/castor2_source_code.zip | 2KB | HTTP |
|---|
| Java compiled code from this article | x-xjavacastor2/castor2_compiled_code.zip | 4KB | HTTP |
|---|
Resources Learn
-
Data binding with
Castor, Part 1: Install and set up Castor (Brett McLaughlin, developerWorks, November
2007): In the initial article of this series, take the first steps to run Castor on your own machine with downloading, installation, setup, configuration, class path issues, and more all covered.
-
Data binding with Castor, Part 3: Map between schemas (Brett McLaughlin, developerWorks, January 2008): Convert data in an unwieldy or inconvenient XML document to your custom Java objects using Castor. You'll no longer be constrained by the names of elements in your XML document, or by the member variable names in your Java classes.
-
Data binding with Castor, Part 4: Bind your Java objects to SQL databases (Brett McLaughlin, developerworks, April 2008): With Castor, turn Java objects into rows within your SQL database. Learn what syntax is the same, what's different, and how you can add SQL to your data binding arsenal.
- The Castor Web
site: Visit the online hub for all things Castor.
-
Castor classes: Read the JavaDoc.
-
xml.com: If you're completely new to XML, try these easy online resources for everything XML.
-
Castor's JDO capabilities (Bruce Snyder, developerWorks, August 2002): Read this older article on developerWorks. Some of the language specifics of this article are out of date, but the concepts are still right on.
-
Practical
Data Binding (Brett McLaughlin, developerWorks, May 2004): Start with the introductory article of a multi-part series for more on Sun's data binding API, JAXB.
-
IBM XML certification: Find out how you can become an IBM-Certified Developer in XML and related technologies.
-
XML technical library: See the developerWorks XML Zone for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks.
-
developerWorks technical events and webcasts: Stay current with technology in these sessions.
- The technology
bookstore: Browse for books on these and other technical topics.
Get products and technologies
-
Java and XML, Third Edition
(Brett McLaughlin and Justin Edelson, O'Reilly Media, Inc.): Covers XML from start to finish, including extensive information on data binding and mapping.
-
Java and XML Data Binding
(Brett McLaughlin, O'Reilly Media, Inc.): In this older book, find details on Castor and the concepts involved in data binding.
-
Castor Professional Services:
Hunting for paid support or help with Castor? Look into Castor's professional services.
-
IBM trial software: Build your next development project with trial software available for download directly from developerWorks.
Discuss
About the author  | 
|  | Brett McLaughlin is a bestselling and award-winning non-fiction author. His books on computer programming, home theater, and analysis and design have sold in excess of 100,000 copies. He has been writing, editing, and producing technical books for nearly a decade, and is as comfortable in front of a word processor as he is behind a guitar, chasing his two sons around the house, or laughing at reruns of Arrested Development with his wife. His last book, Head First Object Oriented Analysis and Design, won the 2007 Jolt Technical Book award. His classic Java and XML remains one of the definitive works on using XML technologies in the Java language. |
Rate this page
|  |