Jersey2 provides inbuilt support for Jackson and JAXB. But Jibx is not supported by default. To use Jibx in conjunction with Jersey2, we are taking the XML input as a stream and after receiving the request, we are parsing it using Jibx. But there is actually a better way of achieving the same using MessageBodyReader and MessageBodyWriter APIs. Here is how this can be achieved:
1. Define a new provider for consuming XML which uses Jibx
2. Register it with Jersey ResourceConfig
@Provider public class JibxXmlProvider implements MessageBodyReader<Object>, MessageBodyWriter<Object> { public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { if(!MediaType.APPLICATION_XML_TYPE.equals(mediaType)){ return false; } try { BindingDirectory.getFactory( type ); } catch (JiBXException e) { return false; } return true; } public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType ) { if(!MediaType.APPLICATION_XML_TYPE.equals(mediaType)){ return false; } try { BindingDirectory.getFactory( type ); } catch (JiBXException e) { return false; } return true; } public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { try { IBindingFactory factory = BindingDirectory.getFactory( type ); IUnmarshallingContext context = factory.createUnmarshallingContext(); return context.unmarshalDocument( entityStream, null ); } catch (Exception e) { e.printStackTrace(); } return null; } public void writeTo(Object obj, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> headers, OutputStream outputStream) throws IOException, WebApplicationException { try { IBindingFactory factory = BindingDirectory.getFactory( type ); IMarshallingContext context = factory.createMarshallingContext(); context.marshalDocument( obj, "UTF-8", null, outputStream ); } catch ( Exception e ) { e.printStackTrace(); } } public long getSize(Object obj, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType ) { return -1; } }
Once this class is defined, register it with Jersey as follows:
public class JerseyResourceInitializer extends ResourceConfig { public JerseyResourceInitializer() { packages(true, "com.adaequare.processing.service"); // This line registers JibxXmlProvider as a new provider. register(JibxXmlProvider.class, MessageBodyReader.class, MessageBodyWriter.class); } }
After this configuration, when ever a new request comes, isReadable method of JibxXmlProvider is called. If it evaluates to true, then readFrom is called for object conversion.
Hope this helps!