Pavel Bucek's Weblog

  • May 5, 2009

Jersey Client - Using ContainerListener

I would like to introduce a possibility to monitor connections made within jersey client api. Monitoring in this case means have knowledge about amount of transferred bytes.

This functionality is provided (as many others) as a client filter, concretely ConnectionListenerFilter. To create ConnectionListenerFilterinstance, you have to implement OnStartConnectionListener. It might look as follows:

class ListenerFactory implements OnStartConnectionListener {
     public ContainerListener onStart(ClientRequest cr) {
         return new Listener();

Looks simple (and it is). This factory creates ContainerListener instance based on ClientRequest. Important note: ClientRequest instance here may be used only for getting values. Any attempt to change anything will produce UnsupportedOperationException.

Ok. Now we need ContainerListener implementation. This class is defined as:

public abstract class ContainerListener {

    public void onSent(long delta, long bytes) {};

    public void onReceiveStart(long totalBytes) {};

    public void onReceived(long delta, long bytes) {};

    public void onFinish() {};

Parameters should be easy to understand, delta is always difference to previous call, bytes is sum of sent/received bytes so far and totalBytes is value from http header (if present, otherwise is set to -1).

Every request has a simple "lifecycle":

1) Send request
2) Receive response

Method onSent is called during step one only when request has some entity. When request is sent and response has no entity, onFinish() is called and that's it. More interesting scenario is when response contains some entity - onReceiveStart is called after sending a request and onReceived during data receiving. Method onFinish is called after whole entity is read.

You will probably have some nice GUI progress bar but I'm going to do only plain text log for now to keep it simple.

class Listener extends ContainerListener {
     public void onSent(long delta, long bytes) {
         System.out.println("onSent: delta: " + delta + " bytes: " + bytes);

     public void onReceiveStart(long totalBytes) {
         System.out.println("onReceiveStart: " + totalBytes);

     public void onReceived(long delta, long bytes) {
         System.out.println("onReceived: delta: " + delta + " bytes: " + bytes);

     public void onFinish() {

And we're almost done! Last thing to do is register our ListenerFactory as a client filter:

    Client c = Client.create();

    c.addFilter(new ConnectionListenerFilter(new ListenerFactory()));

and actually do a request:

    WebResource r = c.resource("http://download.java.net/maven/2/com/sun/jersey/samples/jersey-samples/1.1.0-ea/jersey-samples-1.1.0-ea-project.zip");

Output should look like this:

onReceiveStart: 615534
onReceived: delta: 3677 bytes: 3677
onReceived: delta: 2608 bytes: 6285
onReceived: delta: 2608 bytes: 613949
onReceived: delta: 1585 bytes: 615534

You can experiment with some requests containing entity (so you will see that onSent method is called during sending).

For more information about project Jersey visit http://jersey.dev.java.net

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.