Class MOXyJsonProvider
- All Implemented Interfaces:
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 BehaviorYou 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, "$"); } }
-
Field Summary
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionThe value that will be prepended to all keys that are mapped to an XML attribute.Class<?>
getDomainClass
(Set<Class<?>> domainClasses) Get first non java class if exists.getDomainClasses
(Type genericType) A convenience method to get the domain class (i.e.protected jakarta.xml.bind.JAXBContext
getJAXBContext
(Set<Class<?>> domainClasses, Annotation[] annotations, jakarta.ws.rs.core.MediaType mediaType, jakarta.ws.rs.core.MultivaluedMap<String, ?> httpHeaders) Return the JAXBContext that corresponds to the domain class.By default the JSON-binding will ignore namespace qualification.char
This character (default is '.') separates the prefix from the key name.long
getSize
(Object t, Class<?> type, Type genericType, Annotation[] annotations, jakarta.ws.rs.core.MediaType mediaType) The key that will correspond to the property mapped with @XmlValue.boolean
boolean
boolean
If true empty collections will be marshalled as empty arrays, else the collection will not be marshalled to JSON (default is true).boolean
isReadable
(Class<?> type, Type genericType, Annotation[] annotations, jakarta.ws.rs.core.MediaType mediaType) boolean
If true the grouping element will be used as the JSON key.boolean
isWriteable
(Class<?> type, Type genericType, Annotation[] annotations, jakarta.ws.rs.core.MediaType mediaType) 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) 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.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) 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.readFrom
(Class<Object> type, Type genericType, Annotation[] annotations, jakarta.ws.rs.core.MediaType mediaType, jakarta.ws.rs.core.MultivaluedMap<String, String> httpHeaders, InputStream entityStream) void
setAttributePrefix
(String attributePrefix) Specify a value that will be prepended to all keys that are mapped to an XML attribute.void
setFormattedOutput
(boolean formattedOutput) Specify if the JSON output should be formatted (default is false).void
setIncludeRoot
(boolean includeRoot) Specify if the root node should be included in the JSON message (default is false).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).void
setNamespacePrefixMapper
(Map<String, String> namespacePrefixMapper) By default the JSON-binding will ignore namespace qualification.void
setNamespaceSeparator
(char namespaceSeparator) This character (default is '.') separates the prefix from the key name.void
setValueWrapper
(String valueWrapper) Specify the key that will correspond to the property mapped with @XmlValue.void
setWrapperAsArrayName
(boolean wrapperAsArrayName) If true the grouping element will be used as the JSON key.protected boolean
supportsMediaType
(jakarta.ws.rs.core.MediaType mediaType) 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)
-
Field Details
-
providers
@Context protected jakarta.ws.rs.ext.Providers providers
-
-
Constructor Details
-
MOXyJsonProvider
public MOXyJsonProvider()
-
-
Method Details
-
getAttributePrefix
The value that will be prepended to all keys that are mapped to an XML attribute. By default there is no attribute prefix. -
getDomainClasses
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.JAXBExceptionReturn the JAXBContext that corresponds to the domain class. This method does the following:- If an EclipseLink JAXB (MOXy) JAXBContext is available from a ContextResolver then use it.
- 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
-
getNamespacePrefixMapper
By default the JSON-binding will ignore namespace qualification. If this property is set the portion of the key before the namespace separator will be used to determine the namespace URI. -
getNamespaceSeparator
public char getNamespaceSeparator()This character (default is '.') separates the prefix from the key name. It is only used if namespace qualification has been enabled be setting a namespace prefix mapper. -
getSize
public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations, jakarta.ws.rs.core.MediaType mediaType) - Specified by:
getSize
in interfacejakarta.ws.rs.ext.MessageBodyWriter<Object>
-
getValueWrapper
The key that will correspond to the property mapped with @XmlValue. This key will only be used if there are other mapped properties. -
isFormattedOutput
public boolean isFormattedOutput()- Returns:
- true if the JSON output should be formatted (default is false).
-
isIncludeRoot
public boolean isIncludeRoot()- Returns:
- true if the root node is included in the JSON message (default is false).
- See Also:
-
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). -
isReadable
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, jakarta.ws.rs.core.MediaType mediaType) - Specified by:
isReadable
in interfacejakarta.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" : [ { ... }, { ... }] }
-
isWriteable
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, jakarta.ws.rs.core.MediaType mediaType) - Specified by:
isWriteable
in interfacejakarta.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.JAXBExceptionSubclasses 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:
-
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.JAXBExceptionSubclasses 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:
-
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 interfacejakarta.ws.rs.ext.MessageBodyReader<Object>
- Throws:
IOException
jakarta.ws.rs.WebApplicationException
-
getDomainClass
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
-
setAttributePrefix
Specify a value that will be prepended to all keys that are mapped to an XML attribute. By default there is no attribute prefix. -
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.
-
setIncludeRoot
public void setIncludeRoot(boolean includeRoot) Specify if the root node should be included in the JSON message (default is false).- Parameters:
includeRoot
- - true if the message includes the root node, else false.- See Also:
-
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). -
setNamespacePrefixMapper
By default the JSON-binding will ignore namespace qualification. If this property is set then a prefix corresponding to the namespace URI and a namespace separator will be prefixed to the key. include it you can specify a Map of namespace URI to prefix. -
setNamespaceSeparator
public void setNamespaceSeparator(char namespaceSeparator) This character (default is '.') separates the prefix from the key name. It is only used if namespace qualification has been enabled be setting a namespace prefix mapper. -
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" : [ { ... }, { ... }] }
-
setValueWrapper
Specify the key that will correspond to the property mapped with @XmlValue. This key will only be used if there are other mapped properties. -
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 interfacejakarta.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)
-