Java API for RESTful
Web Services (JAX-RS) enables developers to add a custom entity provider
to the application. Use custom entity providers when you want to use Java types to represent incoming
request message bodies as well as represent outgoing response message
bodies. By adding a custom entity provider, you can deserialize custom
Java types from message bodies and serialize any media type as message
bodies.
About this task
A custom entity
provider is created by annotating a class
with a javax.ws.rs.ext.Provider annotation. The class must implement
the javax.ws.rs.ext.MessageBodyReader interface or the javax.ws.rs.ext.MessageBodyWriter
interface, or both. You must add the provider class to the list of
classes returned in the javax.ws.rs.core.Application subclass getClasses()
method.
- Create a new Java class
that is your custom entity provider. In this procedure,
the example code creates a reader and a writer for com.ibm.json.java.JSONObject types
so that you can use the com.ibm.json.java.JSONObject type
as an incoming request entity parameter and as a return type to contain
the response entity.
public class MyEntityProvider {
}
- Add the @javax.ws.rs.ext.Provider
annotation. Adding
this annotation indicates to the JAX-RS runtime environment that this
class is a JAX-RS provider. If this Provider annotation is not specified,
the runtime environment does not detect that the class is a custom
provider.
@javax.ws.rs.ext.Provider
public class MyEntityProvider {
}
- (optional) Add a @javax.ws.rs.Consumes
or @javax.ws.rs.Produces
annotation if you want to limit the media types that the entity provider
supports. In the following code snippet, the provider
is only invoked when the incoming Content-Type or outgoing Content-Type
is application/json.
@javax.ws.rs.ext.Provider
@javax.ws.rs.Consumes("application/json")
@javax.ws.rs.Produces("application/json")
public class MyEntityProvider {
}
- Implement javax.ws.rs.ext.MessageBodyReader<T> if
the entity provider needs to deserialize a message body.
You
can use the generic type <T> to limit the types
supported by the entity provider.
By defining the message body
reader as javax.ws.rs.ext.MessageBodyReader<com.ibm.json.java.JSONObject>,
the JAX-RS runtime environment knows that only com.ibm.json.java.JSONObject objects
can be produced.
If an entity provider needs to support a
complex set of types, consider implementing javax.ws.rs.ext.MessageBodyReader<Object>.
@javax.ws.rs.ext.Provider
@javax.ws.rs.Consumes("application/json")
@javax.ws.rs.Produces("application/json")
public class MyEntityProvider implements
javax.ws.rs.ext.MessageBodyReader<com.ibm.json.java.JSONObject> {
public boolean isReadable(Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType) {
return com.ibm.json.java.JSONObject.class == type;
}
public com.ibm.json.java.JSONObject readFrom(Class<com.ibm.json.java.JSONObject> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream) throws IOException, WebApplicationException {
/* This InputStream reads from the entityStream and constructs the object. */
com.ibm.json.java.JSONObject retObj = com.ibm.json.java.JSONObject.parse(entityStream);
return retObj;
}
}
- Implement javax.ws.rs.ext.MessageBodyWriter<T> if
the entity provider needs to serialize a message body. You
can implement the MessageBodyReader<T> and MessageBodyWriter<T>
interfaces in the same Java class.
In the following code snippet, only the MessageBodyWriter implementation
is shown.
@Provider
public class MyEntityProvider implements
MessageBodyWriter<Object> {
public long getSize(Object t,
Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType) {
/* return -1 if the content length cannot be determined */
return -1;
}
public boolean isWriteable(Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType) {
return MyType.class == type;
}
public void writeTo(Object t,
Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, WebApplicationException {
entityStream.write(MyType.getBytes());
}
}
- Add the custom entity provider
to the javax.ws.rs.core.Application subclass
and add the provider to the set of classes returned from the getClasses()
method. You can add multiple custom entity providers to
the set of classes returned.
public class MyApplication extends javax.ws.rs.core.Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(MyEntityProvider.class);
return classes;
}
}