The RESTEasy Client Framework is the alternative to the JAX-RS server-side specification. Instead of using JAX-RS annotations to map an incoming request to your RESTful Web Service method, the client framework creates a HTTP request to invoke on a remote RESTful Web Service, which can be any web resource that accepts HTTP requests.
RESTEasy has a client proxy framework that lets you invoke upon a remote HTTP resource by using JAX-RS annotations. You can write a Java interface and use JAX-RS annotations on methods and the interface. For example:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
The RESTEasy API is simple, and based on Apache HttpClient. You generate a proxy, and invoke methods on the proxy. The invoked method is then translated to a HTTP request (based on the method's annotations) and posted to the server. To set it up:
import org.resteasy.plugins.client.httpclient.ProxyFactory;
...
// this initialization only needs to be done once per VM
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
SimpleClient client = ProxyFactory.create(SimpleClient.class, "http://localhost:8081");
client.putBasic("hello world");
import org.resteasy.plugins.client.httpclient.ProxyFactory;
...
// this initialization only needs to be done once per VM
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
SimpleClient client = ProxyFactory.create(SimpleClient.class, "http://localhost:8081");
client.putBasic("hello world");
Copy to ClipboardCopied!Toggle word wrapToggle overflow
See the ProxyFactory Java Documentation for more options. For instance, you may want to fine tune the HttpClient configuration.
@CookieParam creates a cookie header to send to the server. If you allocate your own javax.ws.rs.core.Cookie object and pass it as a parameter to a client proxy method, you do not require @CookieParam — the client framework understands that you are passing a cookie to the server, so no extra metadata is required.
The client framework can use the same providers available on the server. You must manually register them through the ResteasyProviderFactory singleton using the addMessageBodyReader() and addMessageBodyWriter() methods.
When you need to access the response code or the response headers of a client request, the Client-Proxy framework provides two options:
You can return a javax.ws.rs.core.Response.Status enumeration from your method calls, like so:
@Path("/")
public interface MyProxy {
@POST
Response.Status updateSite(MyPojo pojo);
}
@Path("/")
public interface MyProxy {
@POST
Response.Status updateSite(MyPojo pojo);
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
After invoking on the server, the client proxy internally converts the HTTP response code into a Response.Status enumeration.
You can retrieve all data associated with a request with the org.resteasy.spi.ClientResponse interface:
/**
* Response extension for the RESTEasy client framework. Use this, or Response
* in your client proxy interface method return type declarations if you want
* access to the response entity as well as status and header information.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public abstract class ClientResponse<T> extends Response
{
/**
* This method returns the same exact map as Response.getMetadata() except as a map of strings
* rather than objects.
*
* @return
*/
public abstract MultivaluedMap<String, String> getHeaders();
public abstract Response.Status getResponseStatus();
/**
* Unmarshal the target entity from the response OutputStream. You must have type information
* set via <T> otherwise, this will not work.
* <p/>
* This method actually does the reading on the OutputStream. It will only do the read once.
* Afterwards, it will cache the result and return the cached result.
*
* @return
*/
public abstract T getEntity();
/**
* Extract the response body with the provided type information
* <p/>
* This method actually does the reading on the OutputStream. It will only do the read once.
* Afterwards, it will cache the result and return the cached result.
*
* @param type
* @param genericType
* @param <T2>
* @return
*/
public abstract <T2> T2 getEntity(Class<T2> type, Type genericType);
/**
* Extract the response body with the provided type information. GenericType is a trick used to
* pass in generic type information to the resteasy runtime.
* <p/>
* For example:
* <pre>
* List<String> list = response.getEntity(new GenericType<List<String>() {});
* <p/>
* <p/>
* This method actually does the reading on the OutputStream. It will only do the read once. Afterwards, it will
* cache the result and return the cached result.
*
* @param type
* @param <T2>
* @return
*/
public abstract <T2> T2 getEntity(GenericType<T2> type);
}
/**
* Response extension for the RESTEasy client framework. Use this, or Response
* in your client proxy interface method return type declarations if you want
* access to the response entity as well as status and header information.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public abstract class ClientResponse<T> extends Response
{
/**
* This method returns the same exact map as Response.getMetadata() except as a map of strings
* rather than objects.
*
* @return
*/
public abstract MultivaluedMap<String, String> getHeaders();
public abstract Response.Status getResponseStatus();
/**
* Unmarshal the target entity from the response OutputStream. You must have type information
* set via <T> otherwise, this will not work.
* <p/>
* This method actually does the reading on the OutputStream. It will only do the read once.
* Afterwards, it will cache the result and return the cached result.
*
* @return
*/
public abstract T getEntity();
/**
* Extract the response body with the provided type information
* <p/>
* This method actually does the reading on the OutputStream. It will only do the read once.
* Afterwards, it will cache the result and return the cached result.
*
* @param type
* @param genericType
* @param <T2>
* @return
*/
public abstract <T2> T2 getEntity(Class<T2> type, Type genericType);
/**
* Extract the response body with the provided type information. GenericType is a trick used to
* pass in generic type information to the resteasy runtime.
* <p/>
* For example:
* <pre>
* List<String> list = response.getEntity(new GenericType<List<String>() {});
* <p/>
* <p/>
* This method actually does the reading on the OutputStream. It will only do the read once. Afterwards, it will
* cache the result and return the cached result.
*
* @param type
* @param <T2>
* @return
*/
public abstract <T2> T2 getEntity(GenericType<T2> type);
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
All getEntity() methods are deferred until you invoke them. In other words, the response OutputStream is not read until you call one of these methods. The getEntity() method with no parameters can only be used if you have templated the ClientResponse within your method declaration. RESTEasy uses this generic type information to determine which media type the OutputStream is unmarshaled into. The getEntity() methods that take parameters let you specify the Object type the response should be marshaled into. This lets you dynamically extract the desired types at runtime. For example:
@Path("/")
public interface LibraryService {
@GET
@Produces("application/xml")
ClientResponse<LibraryPojo> getAllBooks();
}
@Path("/")
public interface LibraryService {
@GET
@Produces("application/xml")
ClientResponse<LibraryPojo> getAllBooks();
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Include the LibraryPojo in ClientResponse's generic declaration so that the client proxy framework can unmarshal the HTTP response body.