Class MOXyJsonProvider

  • All Implemented Interfaces:
    jakarta.ws.rs.ext.MessageBodyReader<Object>, jakarta.ws.rs.ext.MessageBodyWriter<Object>

    @Produces({"application/json","*/*","application/x-javascript"})
    @Consumes({"application/json","*/*"})
    @Provider
    public class MOXyJsonProvider
    extends Object
    implements jakarta.ws.rs.ext.MessageBodyReader<Object>, jakarta.ws.rs.ext.MessageBodyWriter<Object>

    This is an implementation of MessageBodyReader/MessageBodyWriter that can be used to enable EclipseLink JAXB (MOXy) as the JSON provider.

    Supported Media Type Patterns

    • */json (i.e. application/json and text/json)
    • */*+json

    Below are some different usage options.

    Option #1 - MOXyJsonProvider Default Behavior

    You can use the Application class to specify that MOXyJsonProvider should be used with your JAX-RS application.

     package org.example;
    
     import java.util.*;
     import jakarta.ws.rs.core.Application;
     import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
    
     public class ExampleApplication  extends Application {
    
         @Override
         public Set<Class<?>> getClasses() {
             HashSet<Class<?>> set = new HashSet<Class<?>>(2);
             set.add(MOXyJsonProvider.class);
             set.add(ExampleService.class);
             return set;
         }
    
     }
     
    Option #2 - Customize MOXyJsonProvider

    You can use the Application class to specify a configured instance of MOXyJsonProvider should be used with your JAX-RS application.

     package org.example;
    
     import java.util.*;
     import jakarta.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<?>>(1);
             set.add(ExampleService.class);
             return set;
         }
    
         @Override
         public Set<Object> getSingletons() {
             moxyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
             moxyJsonProvider.setFormattedOutput(true);
             moxyJsonProvider.setIncludeRoot(true);
    
             HashSet<Object> set = new HashSet<Object>(2);
             set.add(moxyJsonProvider);
             return set;
         }
    
     }
     
    Option #3 - Extend MOXyJsonProvider

    You can use MOXyJsonProvider for creating your own MessageBodyReader/MessageBodyWriter.

     package org.example;
    
     import java.lang.annotation.Annotation;
     import java.lang.reflect.Type;
    
     import jakarta.ws.rs.*;
     import jakarta.ws.rs.core.*;
     import jakarta.ws.rs.ext.Provider;
     import jakarta.xml.bind.*;
    
     import org.eclipse.persistence.jaxb.MarshallerProperties;
     import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
    
     @Provider
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
     public class CustomerJSONProvider extends MOXyJsonProvider {
    
         @Override
         public boolean isReadable(Class<?> type, Type genericType,
                 Annotation[] annotations, MediaType mediaType) {
             return getDomainClass(genericType) == Customer.class;
         }
    
         @Override
         public boolean isWriteable(Class<?> type, Type genericType,
                 Annotation[] annotations, MediaType mediaType) {
             return isReadable(type, genericType, annotations, mediaType);
         }
    
         @Override
         protected void preReadFrom(Class<Object> type, Type genericType,
                 Annotation[] annotations, MediaType mediaType,
                 MultivaluedMap<String, String> httpHeaders,
                 Unmarshaller unmarshaller) throws JAXBException {
             unmarshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, "$");
         }
    
         @Override
         protected void preWriteTo(Object object, Class<?> type, Type genericType,
                 Annotation[] annotations, MediaType mediaType,
                 MultivaluedMap<String, Object> httpHeaders, Marshaller marshaller)
                 throws JAXBException {
             marshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, "$");
         }
    
     }
     
    Since:
    2.4
    • Field Detail

      • providers

        @Context
        protected jakarta.ws.rs.ext.Providers providers
    • Constructor Detail

      • MOXyJsonProvider

        public MOXyJsonProvider()
    • Method Detail

      • getDomainClasses

        protected Set<Class<?>> getDomainClasses​(Type genericType)
        A convenience method to get the domain class (i.e. Customer or Foo, Bar) from the parameter/return type (i.e. Customer, List<Customer>, JAXBElement<Customer>, JAXBElement<? extends Customer>, List<JAXBElement<Customer>>, or List<JAXBElement<? extends Customer>> List<Foo<Bar>>).
        Parameters:
        genericType - - The parameter/return type of the JAX-RS operation.
        Returns:
        The corresponding domain classes.
      • getJAXBContext

        protected jakarta.xml.bind.JAXBContext getJAXBContext​(Set<Class<?>> domainClasses,
                                                              Annotation[] annotations,
                                                              jakarta.ws.rs.core.MediaType mediaType,
                                                              jakarta.ws.rs.core.MultivaluedMap<String,​?> httpHeaders)
                                                       throws jakarta.xml.bind.JAXBException
        Return the JAXBContext that corresponds to the domain class. This method does the following:
        1. If an EclipseLink JAXB (MOXy) JAXBContext is available from a ContextResolver then use it.
        2. If an existing JAXBContext was not found in step one, then create a new one on the domain class.
        Parameters:
        domainClasses - - The domain classes we need a JAXBContext for.
        annotations - - The annotations corresponding to domain object.
        mediaType - - The media type for the HTTP entity.
        httpHeaders - - HTTP headers associated with HTTP entity.
        Returns:
        Throws:
        jakarta.xml.bind.JAXBException
      • getSize

        public long getSize​(Object t,
                            Class<?> type,
                            Type genericType,
                            Annotation[] annotations,
                            jakarta.ws.rs.core.MediaType mediaType)
        Specified by:
        getSize in interface jakarta.ws.rs.ext.MessageBodyWriter<Object>
      • isFormattedOutput

        public boolean isFormattedOutput()
        Returns:
        true if the JSON output should be formatted (default is false).
      • isMarshalEmptyCollections

        public boolean isMarshalEmptyCollections()
        If true empty collections will be marshalled as empty arrays, else the collection will not be marshalled to JSON (default is true).
        See Also:
        MarshallerProperties.JSON_MARSHAL_EMPTY_COLLECTIONS
      • isReadable

        public boolean isReadable​(Class<?> type,
                                  Type genericType,
                                  Annotation[] annotations,
                                  jakarta.ws.rs.core.MediaType mediaType)
        Specified by:
        isReadable in interface jakarta.ws.rs.ext.MessageBodyReader<Object>
        Returns:
        true indicating that MOXyJsonProvider will be used for the JSON binding if the media type is of the following patterns */json or */*+json, and the type is not assignable from any of (or a Collection or JAXBElement of) the following:
        • byte[]
        • java.io.File
        • java.io.InputStream
        • java.io.Reader
        • java.lang.Object
        • java.lang.String
        • jakarta.activation.DataSource
      • isWrapperAsArrayName

        public boolean isWrapperAsArrayName()
        If true the grouping element will be used as the JSON key.

        Example

        Given the following class:

         @XmlAccessorType(XmlAccessType.FIELD)
         public class Customer {
        
             @XmlElementWrapper(name="phone-numbers")
             @XmlElement(name="phone-number")
             private List<PhoneNumber> phoneNumbers;
        
         }
         

        If the property is set to false (the default) the JSON output will be:

         {
             "phone-numbers" : {
                 "phone-number" : [ {
                     ...
                 }, {
                     ...
                 }]
             }
         }
         

        And if the property is set to true, then the JSON output will be:

         {
             "phone-numbers" : [ {
                 ...
             }, {
                 ...
             }]
         }
         
        Since:
        2.4.2
        See Also:
        JAXBContextProperties.JSON_WRAPPER_AS_ARRAY_NAME, MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, UnmarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME
      • isWriteable

        public boolean isWriteable​(Class<?> type,
                                   Type genericType,
                                   Annotation[] annotations,
                                   jakarta.ws.rs.core.MediaType mediaType)
        Specified by:
        isWriteable in interface jakarta.ws.rs.ext.MessageBodyWriter<Object>
        Returns:
        true indicating that MOXyJsonProvider will be used for the JSON binding if the media type is of the following patterns */json or */*+json, and the type is not assignable from any of (or a Collection or JAXBElement of) the following:
        • byte[]
        • java.io.File
        • java.lang.Object
        • java.lang.String
        • jakarta.activation.DataSource
        • jakarta.ws.rs.core.StreamingOutput
      • preReadFrom

        protected void preReadFrom​(Class<Object> type,
                                   Type genericType,
                                   Annotation[] annotations,
                                   jakarta.ws.rs.core.MediaType mediaType,
                                   jakarta.ws.rs.core.MultivaluedMap<String,​String> httpHeaders,
                                   jakarta.xml.bind.Unmarshaller unmarshaller)
                            throws jakarta.xml.bind.JAXBException
        Subclasses of MOXyJsonProvider can override this method to customize the instance of Unmarshaller that will be used to unmarshal the JSON message in the readFrom call.
        Parameters:
        type - - The Class to be unmarshalled (i.e. Customer or List)
        genericType - - The type of object to be unmarshalled (i.e Customer or List<Customer>).
        annotations - - The annotations corresponding to domain object.
        mediaType - - The media type for the HTTP entity.
        httpHeaders - - HTTP headers associated with HTTP entity.
        unmarshaller - - The instance of Unmarshaller that will be used to unmarshal the JSON message.
        Throws:
        jakarta.xml.bind.JAXBException
        See Also:
        UnmarshallerProperties
      • preWriteTo

        protected void preWriteTo​(Object object,
                                  Class<?> type,
                                  Type genericType,
                                  Annotation[] annotations,
                                  jakarta.ws.rs.core.MediaType mediaType,
                                  jakarta.ws.rs.core.MultivaluedMap<String,​Object> httpHeaders,
                                  jakarta.xml.bind.Marshaller marshaller)
                           throws jakarta.xml.bind.JAXBException
        Subclasses of MOXyJsonProvider can override this method to customize the instance of Marshaller that will be used to marshal the domain objects to JSON in the writeTo call.
        Parameters:
        object - - The domain object that will be marshalled to JSON.
        type - - The Class to be marshalled (i.e. Customer or List)
        genericType - - The type of object to be marshalled (i.e Customer or List<Customer>).
        annotations - - The annotations corresponding to domain object.
        mediaType - - The media type for the HTTP entity.
        httpHeaders - - HTTP headers associated with HTTP entity.
        marshaller - - The instance of Marshaller that will be used to marshal the domain object to JSON.
        Throws:
        jakarta.xml.bind.JAXBException
        See Also:
        MarshallerProperties
      • readFrom

        public Object readFrom​(Class<Object> type,
                               Type genericType,
                               Annotation[] annotations,
                               jakarta.ws.rs.core.MediaType mediaType,
                               jakarta.ws.rs.core.MultivaluedMap<String,​String> httpHeaders,
                               InputStream entityStream)
                        throws IOException,
                               jakarta.ws.rs.WebApplicationException
        Specified by:
        readFrom in interface jakarta.ws.rs.ext.MessageBodyReader<Object>
        Throws:
        IOException
        jakarta.ws.rs.WebApplicationException
      • getDomainClass

        public Class<?> getDomainClass​(Set<Class<?>> domainClasses)
        Get first non java class if exists.
        Parameters:
        domainClasses -
        Returns:
        first domain class or first generic class or just the first class from the list
      • setFormattedOutput

        public void setFormattedOutput​(boolean formattedOutput)
        Specify if the JSON output should be formatted (default is false).
        Parameters:
        formattedOutput - - true if the output should be formatted, else false.
      • setMarshalEmptyCollections

        public void setMarshalEmptyCollections​(boolean marshalEmptyCollections)
        If true empty collections will be marshalled as empty arrays, else the collection will not be marshalled to JSON (default is true).
        See Also:
        MarshallerProperties.JSON_MARSHAL_EMPTY_COLLECTIONS
      • setWrapperAsArrayName

        public void setWrapperAsArrayName​(boolean wrapperAsArrayName)
        If true the grouping element will be used as the JSON key.

        Example

        Given the following class:

         @XmlAccessorType(XmlAccessType.FIELD)
         public class Customer {
        
             @XmlElementWrapper(name="phone-numbers")
             @XmlElement(name="phone-number")
             private List<PhoneNumber> phoneNumbers;
        
         }
         

        If the property is set to false (the default) the JSON output will be:

         {
             "phone-numbers" : {
                 "phone-number" : [ {
                     ...
                 }, {
                     ...
                 }]
             }
         }
         

        And if the property is set to true, then the JSON output will be:

         {
             "phone-numbers" : [ {
                 ...
             }, {
                 ...
             }]
         }
         
        Since:
        2.4.2
        See Also:
        JAXBContextProperties.JSON_WRAPPER_AS_ARRAY_NAME, MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, UnmarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME
      • supportsMediaType

        protected boolean supportsMediaType​(jakarta.ws.rs.core.MediaType mediaType)
        Returns:
        true for all media types of the pattern */json and */*+json.
      • writeTo

        public void writeTo​(Object object,
                            Class<?> type,
                            Type genericType,
                            Annotation[] annotations,
                            jakarta.ws.rs.core.MediaType mediaType,
                            jakarta.ws.rs.core.MultivaluedMap<String,​Object> httpHeaders,
                            OutputStream entityStream)
                     throws IOException,
                            jakarta.ws.rs.WebApplicationException
        Specified by:
        writeTo in interface jakarta.ws.rs.ext.MessageBodyWriter<Object>
        Throws:
        IOException
        jakarta.ws.rs.WebApplicationException
        See Also:
        MessageBodyWriter.writeTo(java.lang.Object, java.lang.Class, java.lang.reflect.Type, java.lang.annotation.Annotation[], jakarta.ws.rs.core.MediaType, jakarta.ws.rs.core.MultivaluedMap, java.io.OutputStream)