TOP

JAX-RS, JAXB, Jersey, and CDATA

Today I had to reuse my code snippet from the JAXB and CDATA blog post to integrate it into a Jersey web application. The application produces some content which could contain some „strings“ which must be wrapped by a CDATA section. To realize this I implemented a javax.ws.rs.ext.MessageBodyReader and javax.ws.rs.ext.MessageBodyWriter by extending from the class com.sun.jersey.core.provider.jaxb.AbstractJAXBElementProvider. This implementation is registered at the Jersey Application by returning the class object in the com.bosch.im.jaxrs.ImApplication.getClasses() implementation.

import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
 
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
 
import com.google.common.base.Throwables;
import com.sun.jersey.core.provider.jaxb.AbstractJAXBElementProvider;
import com.sun.jersey.spi.inject.Injectable;
 
import CDataXMLStreamWriter;
 
@Provider
@Produces( MediaType.APPLICATION_ATOM_XML ) // replace this by the media type you create in your application
public class CDATAXMLJAXBElementProvider extends AbstractJAXBElementProvider
{
   // Delay construction of factory
   private final Injectable spf;
   private final XMLOutputFactory   xmlOutputFactory = XMLOutputFactory.newInstance();
 
   public CDATAXMLJAXBElementProvider( @Context Injectable spf, @Context Providers ps )
   {
      super( ps );
      this.spf = spf;
   }
 
   @Override
   protected JAXBElement<!--?--> readFrom( Class<!--?--> type, MediaType mediaType, Unmarshaller u, 
      InputStream entityStream )
      throws JAXBException
   {
      return u.unmarshal( getSAXSource( spf.getValue(), entityStream ), type );
   }
 
   @Override
   protected void writeTo( JAXBElement<!--?--> t, MediaType mediaType, Charset c, Marshaller m, 
      OutputStream entityStream )
      throws JAXBException
   {
      CDataXMLStreamWriter cdataStreamWriter = null;
      try
      {
         XMLStreamWriter streamWriter = xmlOutputFactory.createXMLStreamWriter( entityStream, "UTF-8" );
         cdataStreamWriter = new CDataXMLStreamWriter( streamWriter );
         m.marshal( t, cdataStreamWriter );
         cdataStreamWriter.flush();
      }
      catch( XMLStreamException e )
      {
         Throwables.propagate( e );
      }
      finally
      {
         if( cdataStreamWriter != null )
         {
            try
            {
               cdataStreamWriter.close();
            }
            catch( XMLStreamException e )
            {
               // nothing to do
            }
         }
      }
   }
}

Comments are closed.