JAXB

advertisement
JAXB
Java API for XML Binding
The Objective
JAXB is concerned with the translation process
between Java objects and XML documents
• You have a Java object and want to write it to
XML
• You have an XML document and want to turn
it into Java object(s)
Demo code at
https://www.movesinstitute.org/~mcgredo/D
emos
Tasks
There are several possible starting points for working
with Java and XML:
• Write a Java class that can be marshaled to XML
• Given a Java class in “java bean” format, generate an
XML schema
• Given an XML schema, generate Java classes that can
read and write XML
This intro assumes JDK 1.6 (which incorporates Jaxb
2.x)
Annotations
Annotations are a new feature of JDK 1.5 and later. Essentially they
are markers in the Java source code that can be used by
external tools to generate code
Format looks like
@ThisIsAnAnnotation(foo=“bar”)
Annotations can occur only in specific places in the code, including
before a class definition, before a method declaration, before an
ivar, etc.
/** annotations can appear before a method */
@XmlElement
Public float getX()
{ return x;}
Java to XML
POJO (Plain Old Java Object) to XML. Assume that you want to
make a Java class writeable to XML. Suppose you have this:
public class Point
{
float x;
float y;
}
With a getter and setter for each in javabeans format, eg
public void setX(float x)
public float getX()
Annotations Markup
See source code. Things to note:
• @XmlAttribute to designate a field as an attribute rather than an
element. The field must be a primitive schema type (float, int,
etc)
• @XmlRootElement to designate the document root element. You
can also specify a namespace
• @XmlElementWrapper to specify the element that encloses a
repeating series of elements
• Note that you should specify only the getter method as
@XmlAttribute. Jaxb oddly treats both the field and the getter
method as independent entities
• Use @XmlTransient to annotate things that should not be
marshalled to XML.
Generate an XML Schema from
Java Code
Suppose you already have Java code
(annotated or not) and want to generate an
XML schema. How do you do this?
JDK 1.6 includes schemagen in the jdk/bin
directory, which can accomplish this. Typically
you do this with an Ant task, but it’s simpler
to show this from the command line
Schemagen
Note that schemagen can operate on any
javabeans compliant class, not just annotated
ones.
• if it has in ivar called “foo”, it must have
getFoo() and setFoo()
• No-args constructor
Generate XML Schema from Java
C:\Program
Files\java\jdk1.6.0_03\bin\schemagen -cp
src\edu\nps\moves\demo
src\edu\nps\moves\demo*.java
Places the schema into schema1.xsd
Fragment from Schema
<xs:complexType name="point">
<xs:sequence/>
<xs:attribute name="x" type="xs:float" use="required"/>
<xs:attribute name="y" type="xs:float" use="required"/>
<xs:attribute name="z" type="xs:float" use="required"/>
</xs:complexType>
What Happened?
This illustrates one of the possible starting
points: you have Java classes, and want a
corresponding XML schema. We just
generated that schema
Generate Java from Schema
This is another possible starting point: you have
an XML schema, and want to create Java
classes that correspond to that
JAXB can generate simple java beans classes
with getters and setters that know how to
unmarshall themselves from XML
This simplifies the parsing process for small-tomedium XML documents: use JAXB to read it
into Java classes
xjc
The program that does this is xjc, also included in the
bin director of the JDK
The command:
"c:\Program
Files\Java\jdk1.6.0_03\bin\xjc" -d
src\jaxb -p edu.nps.moves.jaxb
schema1.xsd
-p specifies the package the generated java will use, -d
the directory to which the classes should be written,
schema1.xsd the schema to use when creating the
Fragment of generated code
public class Point {
@XmlAttribute(required = true)
protected float x;
@XmlAttribute(required = true)
protected float y;
ObjectFactory
You generally create new instances of the generated
classes via ObjectFactory
See Usage.java class for examples
NOTE: for obscure reasons, JAXB does not insert the
@XmlRootElement annotation where it “should”. The
easiest way to handle this is to just add the
annotation manually to the Points class, the root
element of the document. There are other
workarounds, but they appear to be experimental
right now
Marshalling
See Usage.java for full examples of marshalling and unmarshalling
to XML
JAXBContext context = JAXBContext.newInstance(Points.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
true);
marshaller.marshal(pointContainer, new
FileOutputStream("example.xml"));
Unmarshalling
Unmarshaller unmarshaller =
context.createUnmarshaller();
Points unmarshalledObject =
(Points)unmarshaller.unmarshal(new
FileInputStream("example.xml"));
What Happened?
• Annotate a POJO Java class so we can
marshal & unmarshall it to XML
• Given a Java class, generate an XML schema
• Given an XML schema, generate Java classes
Download