XML Support

RESTful

XML Support


The MessageBodyWriters and MessageBodyReaders are used by Jersey to parse incoming request and create outgoing responses for custom user representations. But it is more convenient and recommended to use XML representations. Jersey supports low level data types used for direct manipulation and JAXB XML entities.

1. Low Level XML Support

Jersey supports such low level data types: StreamSource, SAXSource, DOMSource and Document.  These types can be used as the return type or as a method parameter.

Example 1.1. Low level XML support

The following example resource has methods, which consumes and produces mentioned above types.

@Path("exams")
public class ExamService {
    @POST
    @Path("StreamSource")
    public StreamSource getStreamSource(StreamSource streamSource) {
        return streamSource;
    }

    @POST
    @Path("SAXSource")
    public SAXSource getSAXSource(SAXSource saxSource) {
        return saxSource;
    }

    @POST
    @Path("DOMSource")
    public DOMSource getDOMSource(DOMSource domSource) {
        return domSource;
    }

    @POST
    @Path("Document")
    public Document getDocument(Document document) {
        return document;
    }
}

Example 1.2. Jersey Client

The code demonstrates how to write jersey client to test the getStreamSource method from the previous example. The type should be set to APPLICATION_XML_TYPE. It is post very simple xml - "<exam/>". The same approach can be used to test getSAXSource, getDOMSource and getDocument methods.

Client client = Client.create();
WebResource resource = client.resource(".../exams/StreamSource");
String result = resource.type(MediaType.APPLICATION_XML_TYPE).post(String.class, "<exam/>");
System.out.println(result);

The result is:

<?xml version="1.0" encoding="UTF-8"?><exam/>

2. JAXB Support

Example 2.1. Exam class

We will use simple Exam class in our resource, which has just id and name. If non default XML representation is required, other JAXB annotations should be used.

@XmlRootElement
public class Exam {
    public int id;
    public String name;
}

Example 2.2. Resource

@Path("exam")
public class ExamService {
    @GET
    @Produces(MediaType.APPLICATION_XML)
    public Exam getExam() {
        Exam exam = new Exam();
        exam.id = 3;
        exam.name = "OCEJWSD6";
        return exam;
    }
}

 The resource can be accessed by GET .../exam. The result will be:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<exam>
   <id>3</id>
   <name>OCEJWSD6</name>
</exam>

Example 2.3. Jersey Client

 It is possible to use Jersey client to test our resource, which gives the possibility to receive Exam object instead of String:

Client client = Client.create();
WebResource resource = client.resource("../exam");
Exam result = resource.accept(MediaType.APPLICATION_XML_TYPE).get(Exam.class);

3. POJOs

If there isn't possibility to add JAXB annotations to the source, JAXBElement class can be used.

Example 3.1. Resource using JAXBElement class

The resource has get and set methods:

@Path("exam")
public class ExamService {
    @GET
    @Produces(MediaType.APPLICATION_XML)
    public JAXBElement<Exam> getExam() {
        Exam exam = new Exam();
        exam.id = 3;
        exam.name = "OCEJWSD6";
        return new JAXBElement<Exam>(new QName("exam"), Exam.class, exam);
    }

    @POST
    @Consumes(MediaType.APPLICATION_XML)
    public void setExam(JAXBElement<Exam> exam) {
        System.out.println("setExam " + exam.getValue().name);
        System.out.println("setExam " + exam.getValue().id);
    }
}

The resource can be accessed by GET .../exam. The result will be:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<exam>
   <id>3</id>
   <name>OCEJWSD6</name>
</exam>

Example 3.2. Jersey Client to test Resource with JAXBElement class

 The code shows how to test get and post requests of the resource from the previous example using Jersey client:

Client client = Client.create();
WebResource resource = client.resource(".../exam");
// GET
GenericType<JAXBElement<Exam>> examType = new GenericType<JAXBElement<Exam>>() {};
Exam exam1 =  resource.accept(MediaType.APPLICATION_XML_TYPE).get(examType).getValue();
System.out.println(exam1.name);
System.out.println(exam1.id);

// POST
Exam exam2 = new Exam();
exam2.id = 1;
exam2.name = "OCJP 6";
resource.post(new JAXBElement<Exam>(new QName("exam"), Exam.class, exam2));

4. Using custom JAXBContext

Sometimes it is necessary to use custom JAXBContext to set some specific things, for example to set different classloader. Creating JAXBContext is expensive operation, so it is advices to create one instance for Jersey.

Example 4.1. Using custom JAXBContext

Example demonstrates simple JAXBContext creation.

@Provider
public class ExamJAXBContextProvider implements ContextResolver<JAXBContext> {
    private JAXBContext context = null;

    public JAXBContext getContext(Class<?> aClass) {
        if (aClass != Exam.class) {
            return null;
        }
        if (context == null) {
            try {
                context = JAXBContext.newInstance(Exam.class);
            } catch (JAXBException e) {
                System.out.println(e.getMessage());
            }
        }
        return context;
    }
}

Example 4.2. Using Provider with Jersey Client

The code below shows how to declare provider in client config:

ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getClasses().add(ExamJAXBContextProvider.class);
Client client = Client.create(clientConfig);

 

Sources:  Jersey Tutorial - XML Support



0 comments
Leave your comment: