Providers interface allows runtime lookup of registered provider instances. Following is its declaration:
package javax.ws.rs.ext;
....
public interface Providers {
<T> MessageBodyReader<T> getMessageBodyReader(Class<T> type, Type genericType,
Annotation[] annotations, MediaType mediaType);
<T> MessageBodyWriter<T> getMessageBodyWriter(Class<T> type, Type genericType,
Annotation[] annotations, MediaType mediaType);
<T extends Throwable> ExceptionMapper<T> getExceptionMapper(Class<T> type);
<T> ContextResolver<T> getContextResolver(Class<T> contextType, MediaType mediaType);
}
The instance of this interface can be injected with @Context annotation. It is injectable in both client and server providers.
This interface typically meant to be injected in a provider class wishing to use other provider to delegate some functionality.
We have already seen an example of Providers.getContextResolver() here. In the following example we are going to use Providers.getMessageBodyWriter() .
Example
Following example resource is meant to return the response in CSV format:
@Path("/persons")
public class PersonsResource {
@GET
@Produces("text/csv")
public List<Person> getPersons() {
return Arrays.asList(
new Person("Tina", 35),
new Person("Charlie", 40));
}
}
public class Person {
private String name;
private int age;
.............
}
Injecting Providers instance
To convert POJOs to CSV format, we are going to implement MessageBodyWriter:
@Provider
@Produces("text/csv")
public class CsvWriter<T> implements MessageBodyWriter<List<T>> {
@Context
Providers providers;
@Override
public void writeTo(List<T> ts, Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, WebApplicationException {
String response = "";
for (T t : ts) {
try {
Class<?> c = t.getClass();
//using Java Bean API to access property values
BeanInfo beanInfo = Introspector.getBeanInfo(c);
String temp = "";
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
if (pd.getName().equals("class")) {//skip getClass()
continue;
}
Object o = pd.getReadMethod().invoke(t);
temp += "," + o;
}
if (temp.length() > 0) {
temp = temp.substring(1);
response += temp + "\n";
}
} catch (Exception e) {
throw new WebApplicationException(e);
}
}
//using Providers instance
MessageBodyWriter<String> plainTextWriter = providers.getMessageBodyWriter(String.class,
genericType, annotations, MediaType.TEXT_PLAIN_TYPE);
plainTextWriter.writeTo(response, String.class, genericType, annotations, mediaType,
httpHeaders, entityStream);
}
@Override
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public long getSize(List<T> ts, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return -1;
}
}
As seen above, the actual responsibility of writing response to output stream is delegated to the default writer which handles plain text.
To try examples, run embedded tomcat (configured in pom.xml of example project below):
mvn tomcat7:run-war
The JAX-RS client
public class ExampleClient {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
WebTarget target =
client.target("http://localhost:8080/persons");
Response response = target.request()
.get();
System.out.printf("status: %s%n", response.getStatus());
System.out.printf("-- response body --%n%s%n", response.readEntity(String.class));
}
} Outputstatus: 200 -- response body -- 35,Tina 40,Charlie
Example ProjectDependencies and Technologies Used: - jersey-server 2.25.1: Jersey core server implementation.
- jersey-container-servlet 2.25.1: Jersey core Servlet 3.x implementation.
- JDK 1.8
- Maven 3.3.9
|