Java Reference
In-Depth Information
of the output. Finally, the
writeTo()
method does all the heavy lifting and writes the content
out to the HTTP response buffer. Let's implement this interface to support JAXB:
@Provider
@Produces
(
"application/xml"
)
public
public class
class
JAXBMarshaller
JAXBMarshaller
implements
implements
MessageBodyWriter
{
public
public
boolean
boolean
isWriteable
(
Class
<?>
type
,
Type genericType
,
Annotation annotations
[],
MediaType mediaType
) {
return
return
type
.
isAnnotationPresent
(
XmlRootElement
.
class
);
}
We start off the implementation of this class by annotating it with the
@javax.ws.rs.ext.Provider
annotation. This tells JAX-RS that this is a deployable JAX-
RS component. We must also annotate it with
@Produces
to tell JAX-RS which media types
this
MessageBodyWriter
supports. Here, we're saying that our
JAXBMarshaller
class sup-
ports
application/xml
.
The
isWriteable()
method is a callback method that tells the JAX-RS runtime whether or
not the class can handle writing out this type. JAX-RS follows this algorithm to find an ap-
propriate
MessageBodyWriter
to write out a Java object into the HTTP response:
1. First, JAX-RS calculates a list of
MessageBodyWriters
by looking at each writer's
@Produces
annotation to see if it supports the media type that the JAX-RS resource
method wants to output.
2. This list is sorted, with the best match for the desired media type coming first. In oth-
er words, if our JAX-RS resource method wants to output
application/xml
and we
have three
MessageBodyWriters
(one produces
application/*
, one supports any-
thing
*/*
, and the last supports
application/xml
), the one producing
application/
xml
will come first.
3. Once this list is calculated, the JAX-RS implementation iterates through the list in or-
der, calling the
MessageBodyWriter.isWriteable()
method. If the invocation re-
turns
true
, that
MessageBodyWriter
is used to output the data.
The
isWriteable()
method takes four parameters. The first one is a
java.lang.Class
that
is the type of the object that is being marshalled. We determine the type by calling the
getClass()
method of the object. In our example, we use this parameter to find out if our
object's class is annotated with the
@XmlRootElement
annotation.
The second parameter is a
java.lang.reflect.Type
. This is generic type information
about the object being marshalled. We determine it by introspecting the return type of the
JAX-RS resource method. We don't use this parameter in our
JAXBMar-