Search code examples
jsoncxfeclipselinkmoxyjettison

What is the best way of replace CXF's JSONProvider (Jettison based) with MOXy?


I was wondering why MOXy is not providing a JSONProvider class similar to JACKSON to replace the default JSON provider in a jax-rs implementation?

This would be the easiest way to deal with all classes in a certain package. What I ended up doing was to do the following as I feel that custom context resolver or MessageBodyWriter/Reader are mostly suited to handle certain classes, but not to handle all classes in a package especially if you have many classes.

Am I right? What are your thoughts? What is the best way to replace Jettison with MOXy in CXF to handle all classes in a package?

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.apache.cxf.jaxrs.provider.json.JSONProvider;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.JAXBContextFactory;

public class MyJSONProvider<T> extends JSONProvider<T> {
    private static JAXBContext jaxbContext = null;
    static {
        try {
            jaxbContext = JAXBContextFactory.createContext("com.bp.bs", null);
        } catch (JAXBException jaxbe) {
            jaxbe.printStackTrace();
            throw new ExceptionInInitializerError(jaxbe);
        }
    }

    @Override
    public void writeTo(T obj, Class<?> cls, Type genericType,
            Annotation[] anns, MediaType m,
            MultivaluedMap<String, Object> headers, OutputStream os)
            throws IOException, WebApplicationException {
        Marshaller marshaller = null;
        try {
            marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(MarshallerProperties.MEDIA_TYPE,
                    "application/json");
            marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
            marshaller.marshal(obj, os);
        } catch (JAXBException jaxbe) {
            jaxbe.printStackTrace();
        }
    }
}

Solution

  • EclipseLink JAXB (MOXy) offers the org.eclipse.persistence.jaxb.rs.MOXyJsonProvider class that can be used to enable it as the JSON-provider.

    Below is an example of a JAX-RS Application class that configures MOXyJsonProvider.

    package org.example;
    
    import java.util.*;
    import javax.ws.rs.core.Application;
    import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
    
    public class CustomerApplication  extends Application {
    
        @Override
        public Set<Class<?>> getClasses() {
            HashSet<Class<?>> set = new HashSet<Class<?>>(2);
            set.add(MOXyJsonProvider.class);
            set.add(CustomerService.class);
            return set;
        }
    
    }
    

    MOXyJsonProvider was added in EclipseLink 2.4.0. The latest version is EclipseLink 2.4.1 which can be downloaded from the following link:

    For More Information