In a previous post I demonstrated how you can implement a MessageBodyReader/MessageBodyWriter to leverage EclipseLink JAXB (MOXy)'s JSON binding in a JAX-RS service. MOXy now includes an implementation (MOXyJsonProvider) that can be used directly or extended to make the integration even easier.
Using MOXyJsonProvider
Default Behaviour
You can use a JAX-RS Application class to specify that MOXyJsonProvider should be used with your JAX-RS application.
Default Behaviour
You can use a JAX-RS Application class to specify that MOXyJsonProvider should be used with your JAX-RS application.
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;
}
}
Configuration Options
You can also use a JAX-RS Application class to specify an instance
of MOXyJsonProvider to be used with your JAX-RS application. This approach allows you customize the different configuration options offered by the 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<?>>(1);
set.add(ExampleService.class);
return set;
}
@Override
public Set<Object> getSingletons() {
MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
moxyJsonProvider.setAttributePrefix("@");
moxyJsonProvider.setFormattedOutput(true);
moxyJsonProvider.setIncludeRoot(true);
moxyJsonProvider.setMarshalEmptyCollections(false);
moxyJsonProvider.setValueWrapper("$");
Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
namespacePrefixMapper.put("http://www.example.org/customer", "cust");
moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);
moxyJsonProvider.setNamespaceSeparator(':');
HashSet<Object> set = new HashSet<Object>(1);
set.add(moxyJsonProvider);
return set;
}
}
WEB-INF/web.xml
A web.xml file is used to configure the Application class. Below is a web.xml I used in a previous example (see Creating a RESTful Web Service - Part 4/5) extended to reference the CustomerApplication class from this post.
A web.xml file is used to configure the Application class. Below is a web.xml I used in a previous example (see Creating a RESTful Web Service - Part 4/5) extended to reference the CustomerApplication class from this post.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.example.CustomerApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<persistence-context-ref>
<persistence-context-ref-name>persistence/em</persistence-context-ref-name>
<persistence-unit-name>CustomerService</persistence-unit-name>
</persistence-context-ref>
</web-app>
Extending MOXyJsonProvider
You can also extend MOXyJsonProvider to create your own
MessageBodyReader/MessageBodyWriter. The preReadFrom and preWriteTo methods can be overridden to customize the Unmarshaller/Marshaller that will be used by MOXy.
package org.example;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.Provider;
import javax.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, "$");
}
}
Further Reading
If you enjoyed this post then you may also be interested in:
- MOXy as Your JAX-RS JSON Provider - Client Side
- Creating a RESTful Service
- Part 1 - The Database
- Part 2 - Mapping the Database to JPA Entities
- Part 3 - Mapping JPA entities to XML (using JAXB)
- Part 4 - The RESTful Service
- Part 5 - The Client
- MOXy's XML Metadata in a JAX-RS Service
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.