Unmarshalling XML using JAXB in restlet's acceptRepresentation method
-
21-08-2019 - |
Question
I've created an XML schema by annotating an existing Java domain model class, now when I try to use JAXB to unmarshall the representation received within my restlet webservice I'm getting a host of errors no matter what I seem to try. I'm new to both restlets and JAXB so pointing me in the direction of a decent example of using both would be helpful only one I've managed to find so far was here: Example
My errors are:
If I try to use the restlet.ext.jaxb JaxbRepresentation:
@Override
public void acceptRepresentation(Representation representation)
throws ResourceException {
JaxbRepresentation<Order> jaxbRep = new JaxbRepresentation<Order>(representation, Order.class);
jaxbRep.setContextPath("com.package.service.domain");
Order order = null;
try {
order = jaxbRep.getObject();
}catch (IOException e) {
...
}
from this I get a
java.io.IOException: Unable to unmarshal the XML representation.Unable to locate unmarshaller.
exception at jaxbRep.getObject()
So I also tried a different approach to see if that made a difference, using the following code instead:
@Override
public void acceptRepresentation(Representation representation)
throws ResourceException {
try{
JAXBContext context = JAXBContext.newInstance(Order.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Order order = (Order) unmarshaller.unmarshal(representation.getStream());
} catch( UnmarshalException ue ) {
...
} catch( JAXBException je ) {
...
} catch( IOException ioe ) {
...
}
However this also gives me the following exception when call to JAXBContext.newInstance is made.
java.lang.NoClassDefFoundError: javax/xml/bind/annotation/AccessorOrder
Thanks in advance for any advice.
Solution
Seems there was a couple of errors here, I never had an ObjectFactory class and I was using out of date versions of the JAXB libraries, after adding this class and updating to 2.1.11 it seems to work now
OTHER TIPS
The Jaxb Extension for Restlet didn't work for me too. I got the same Unable to marshal
Exception along with some more Exceptions. Strangely the JAXBContext.newInstance()
call itself worked fine in my code. Because of that, i wrote a simple JaxbRepresenetation class:
public class JaxbRepresentation extends XmlRepresentation {
private String contextPath;
private Object object;
public JaxbRepresentation(Object o) {
super(MediaType.TEXT_XML);
this.contextPath = o.getClass().getPackage().getName();
this.object = o;
}
@Override
public Object evaluate(String expression, QName returnType) throws Exception {
final XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(this);
return xpath.evaluate(expression, object, returnType);
}
@Override
public void write(OutputStream outputStream) throws IOException {
try {
JAXBContext ctx = JAXBContext.newInstance(contextPath);
Marshaller marshaller = ctx.createMarshaller();
marshaller.marshal(object, outputStream);
} catch (JAXBException e) {
Context.getCurrentLogger().log(Level.WARNING, "JAXB marshalling error!", e);
throw new IOException(e);
}
}
}