Communicating with HTTP servers

To send a command to an HTTP server, you need a SenderDestination object to communicate with an end point. The SenderDestination object is responsible for queuing messages for delivery, and retrieving incoming messages for delivery. The DestinationFactory class creates and maintains a list of Destination objects that you can use to communicate with an end point.

Before you create a SenderDestination, you should check whether one exists by invoking getSenderDestination(). You can access an existing destination by providing the name of the Context object that you supplied when you invoked any of the DestinationFactory.create...() methods.

When you finish exchanging data with an end point, you should invoke DestinationFactory.release() or DestinationFactory.destory(). The release() method removes the association between a Destination and the inbound and outbound message queues. After you invoke release(), the API continues to attempt the delivery of messages in the queue. You can use release() when your application is not in a state to send and receive messages. In addition to removing the association between a Destination and the a message queue, destroy() also destroys the message queue. After you invoke destory(), any messages in the queue will be deleted.

A message contains the details of your command, including the HTTP request method and any additional data that you require. If you do not specify all parameters for your message, default values are provided by the Communication API.

After you send your message, you may need to listen for a response. For BlockingSenderDestination objects, you need to create a Thread object when you invoke one of the sendReceive() methods. For NonBlockingSenderDestination objects, you must create a MessageListener object to receive the response.

In either case, you need to process a Message object that contains the response. By default, the body of the Message contains the raw response data. You can choose to specify a message processor from the net.rim.device.api.io.parser package, or create your own using the MessageProcessor interface.

If necessary, you can connect multiple message processors together. The MessageProcessorChain class shares memory between the MessageProcessor objects to improve efficiency. For example, if you receive video data that uses custom encoding and compression, you can separate the decoding and decompression logic into separate message processors, and then use MessageProcessorChain to group them together.

Request data using a BlockingSenderDestination object

  1. Import the required classes and interfaces.
    import net.rim.device.api.io.messaging.*;
    import net.rim.device.api.io.URI;
  2. Create a thread from which to call BlockingSenderDestination.sendReceive().
    Thread t = new Thread( new Runnable()
    {
        public void run()
        {
  3. Create a Message object to hold the response from the URL.
            Message response = null;
  4. Create a URI object to pass to the DestinationFactory class.
            URI uri = new URI("http://www.blackberry.com");
  5. Create a BlockingSenderDestination object.
            BlockingSenderDestination bsd = null;
  6. Retrieve the BlockingSenderDestination object for your context, if one exists.
            try
            {
                bsd = (BlockingSenderDestination) 
                          DestinationFactory.getSenderDestination
                                                 ("MyContext", uri);
  7. If no BlockingSenderDestination exists, create one.
                if(bsd == null)
                {
                    bsd = DestinationFactory.createBlockingSenderDestination
                                                 (new Context("MyContext"), uri);
                }
  8. Send a message and wait for the response.
                response = bsd.sendReceive();
  9. If the web service sent a response, process the response.
                if(response != null)
                {
                    processResponse(response);
                }
            }
  10. Catch any errors that occur if the message could not be sent for some reason.
            catch (Exception e)
            {
                // Process the error
            }
  11. Release the BlockingSenderDestination.
            finally
            {
                if(bsd != null)
                {
                    bsd.release();
                }
            }
        }
    
    });
  12. Start the thread.
    t.start();
After you finish: If your processResponse() updates the UI, you must do so on the main event thread, not on the thread that you created in this task. For more information, read the knowledge base article at http://supportforums.blackberry.com/t5/Java-Development/Manage-UI-interactions/ta-p/502378.

For a complete code sample, see "Code sample: Requesting data using a BlockingSenderDestination object".

Back To Top

Code sample: Requesting data using a BlockingSenderDestination object

import net.rim.device.api.io.messaging.*;
import net.rim.device.api.io.URI;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import java.io.*;

public class NetworkSample extends UiApplication 
{
    public static void main(String[] args) 
    {
        NetworkSample app = new NetworkSample();
        app.enterEventDispatcher();
    }
    public NetworkSample() 
    {
        pushScreen(new BlockingSenderSample());
    }
}

class BlockingSenderSample extends MainScreen implements FieldChangeListener
{

    ButtonField _btnBlock = new ButtonField(Field.FIELD_HCENTER);

    private static UiApplication _app = UiApplication.getUiApplication();

    private String _result;

    public BlockingSenderSample()
    {
        _btnBlock.setChangeListener(this);
        _btnBlock.setLabel("Fetch page");

        add(_btnBlock);
    }

    public void fieldChanged(Field button, int unused)
    {

        if(button == _btnBlock)
        {

            Thread t = new Thread(new Runnable() 
            {
                public void run()
                {
                    Message response = null;
                    String uriStr = "http://www.blackberry.com";
                    BlockingSenderDestination bsd = null;
                    try
                    {
                        bsd = (BlockingSenderDestination)
                                   DestinationFactory.getSenderDestination
                                       ("CommAPISample", URI.create(uriStr));
                        if(bsd == null)
                        {
                            bsd =
                              DestinationFactory.createBlockingSenderDestination
                                  (new Context("CommAPISample"),
                                   URI.create(uriStr)
                                   );
                        }

                        // Send message and wait for response
                        response = bsd.sendReceive();

                        if(response != null)
                        {
                            BSDResponse(response);
                        }
                    }
                    catch(Exception e)
                    {
                        // process the error
                    }
                    finally
                    {
                        if(bsd != null)
                        {
                            bsd.release();
                        }
                    }
                }

            });
            t.start();
            
        }
    }

    private void BSDResponse(Message msg)
    {
        if (msg instanceof ByteMessage)
        {
            ByteMessage reply = (ByteMessage) msg;
            _result = (String) reply.getStringPayload();
        } else if(msg instanceof StreamMessage)
        {
            StreamMessage reply = (StreamMessage) msg;
            InputStream is = reply.getStreamPayload();
            byte[] data = null;
            try {
                data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
            } catch (IOException e) {
                // process the error
            }
            if(data != null)
            {
                _result = new String(data);
            }
        }

        _app.invokeLater(new Runnable() {

            public void run() {
                _app.pushScreen(new HTTPOutputScreen(_result));
            }

        });

    }

}


class HTTPOutputScreen extends MainScreen 
{

    RichTextField _rtfOutput = new RichTextField();

    public HTTPOutputScreen(String message)
    {
        _rtfOutput.setText("Retrieving data. Please wait...");
        add(_rtfOutput);
        showContents(message);
    }

    // After the data has been retrieved, display it
    public void showContents(final String result) 
    {
        UiApplication.getUiApplication().invokeLater(new Runnable() 
        {

            public void run() 
            {
                _rtfOutput.setText(result);
            }
        });
    }
}
Back To Top

Request data using a NonBlockingSenderDestination object

Before you begin: To request data using the NonBlockingSenderDestination class, create an object that implements the MessageListener interface. For more information, see "Implement the MessageListener interface".
  1. Import the required classes and interfaces.
    import net.rim.device.api.io.messaging.*;
    import net.rim.device.api.io.URI;
  2. Create a Message object to hold the response from the URL.
    Message response = null;
  3. Create a URI object to pass to the DestinationFactory class.
    URI uri = new URI("http://www.blackberry.com");
  4. Create a NonBlockingSenderDestination object.
    NonBlockingSenderDestination nbsd = null;
  5. Create a reference to your MessageListener.
    MyMessageListener msgListener = new MyMessageListener();
  6. Retrieve the NonBlockingSenderDestination object for your context, if one exists.
    try
    {
        nbsd = (BlockingSenderDestination) DestinationFactory.getSenderDestination
                                              ("MyContext", uri);
  7. If no NonBlockingSenderDestination exists, create one.
        if(nbsd == null)
        {
            nbsd = DestinationFactory.createNonBlockingSenderDestination
                              (new Context("MyContext"), uri, msgListener);
        }
  8. Send a message to the web service.
        nbsd.send();
  9. Catch any errors that occur if the message could not be sent for some reason.
        catch (Exception e)
        {
            // Process the error
        }
After you finish: Release the NonBlockingSenderDestination when you are done processing the response.

For a complete code sample, see "Code sample: Request data using a NonBlockingSenderDestination object"

Back To Top

Implement the MessageListener interface

You can use the MessageListener interface to receive messages that are sent by a NonBlockingSenderDestination object, or push messages that are sent from a push initiator.
  1. Import the required classes and interfaces.
    import net.rim.device.api.io.messaging.*;
    
    import java.io.IOException;
    import java.io.InputStream;
  2. Define a class that implements the MessageListener interface.
    public class MyMessageListener implements MessageListener {
  3. Implement onMessage().
        public void onMessage(Destination dest, Message incomingMessage)
        {
  4. Initialize a String variable to hold the response data.
            String payload = null;
  5. If the response is a ByteMessage object, retrieve the response as a String and assign it to payload.
            if (incomingMessage instanceof ByteMessage)
            {
                ByteMessage reply = (ByteMessage) incomingMessage;
                payload = (String) reply.getStringPayload();
            }
  6. If the response is a StreamMessage, retrieve the response as an InputStream object.
            else if(incomingMessage instanceof StreamMessage)
            {
                StreamMessage reply = (StreamMessage) incomingMessage;
                InputStream is = reply.getStreamPayload();
    1. If the response is small, convert the contents of the stream into a byte array.
                  byte[] data = null;
                  try 
                  {
                      data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
                  } catch (IOException e) 
                  {
                       // process the error
                  }
    2. If the conversion was successful, convert the byte array to a String and assign it to payload.
                  if(data != null)
                  {
                      payload = new String(data);
                  }
              }
  7. If payload contains data, display it.
            if(payload!=null)
            {
                synchronized(Application.getEventLock())
                {
                    UiApplication.getUiApplication().pushScreen
                                                  (new HTTPOutputScreen(payload));
                }
    
    
            }
After you finish: Implement onMessageCancelled() and onMessageFailed() to process other notifications.

For a complete code sample, see "Code sample: Request data using a NonBlockingSenderDestination object"

Back To Top

Code sample: Requesting data using a NonBlockingSenderDestination object

import net.rim.device.api.io.URI;
import net.rim.device.api.io.messaging.*;
import net.rim.device.api.ui.*
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.system.Application;
import java.io.*;

public class NetworkSample extends UiApplication 
{
    public static void main(String[] args) 
    {
        NetworkSample app = new NetworkSample();
        app.enterEventDispatcher();
    }
    public NetworkSample() 
    {
        pushScreen(new NonBlockingSenderSample());
    }
}

class NonBlockingSenderSample extends MainScreen 
                                                 implements FieldChangeListener
{

    ButtonField _btnNonBlock = new ButtonField(Field.FIELD_HCENTER);

    private static UiApplication _app = UiApplication.getUiApplication();

    public NonBlockingSenderSample()
    {
        _btnNonBlock.setChangeListener(this);
        _btnNonBlock.setLabel("Fetch page");

        add(_btnNonBlock);
    }

    public void fieldChanged(Field button, int unused)
    {

        if(button == _btnNonBlock)
        {
            NonBlockingSenderDestination destination = null;
            try
            {
                URI uri = URI.create("http://www.blackberry.com");

                NBSDMsgListener responseListener = new NBSDMsgListener();
                destination = (NonBlockingSenderDestination)
                                  DestinationFactory.getSenderDestination
                                      ("CommAPISample", uri);
                if (destination == null)
                {
                    destination =
                        DestinationFactory.createNonBlockingSenderDestination
                            (new Context("CommAPISample"), uri, responseListener);
                }

                // Send message to retrieve the response
                destination.send();

            }


            catch(Exception e)
            {
                // process the error
            }

        }
    }

}

class NBSDMsgListener implements MessageListener 
{

    public void onMessage(Destination dest, Message msg) 
    {

        String payload = null;

        if (msg instanceof ByteMessage)
        {
            ByteMessage reply = (ByteMessage) msg;
            payload = (String) reply.getStringPayload();
        } else if(msg instanceof StreamMessage)
        {
            StreamMessage reply = (StreamMessage) msg;
            InputStream is = reply.getStreamPayload();
            byte[] data = null;
            try {
                data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
            } catch (IOException e) {
            }
            if(data != null)
            {
                payload = new String(data);
            }
        }
        if(payload!=null)
        {
            synchronized(Application.getEventLock())
            {
                UiApplication.getUiApplication().pushScreen
                                                (new HTTPOutputScreen(payload));
            }


        }
    }

    public void onMessageCancelled(Destination arg0, int arg1) 
    {
        // process message cancelled notification
    }

    public void onMessageFailed(Destination arg0, MessageFailureException arg1) 
    {
        // process message failed notification
    }

}

class HTTPOutputScreen extends MainScreen 
{

    RichTextField _rtfOutput = new RichTextField();

    public HTTPOutputScreen(String message)
    {
        _rtfOutput.setText("Retrieving data. Please wait...");
        add(_rtfOutput);
        showContents(message);
    }

    // After the data has been retrieved, display it
    public void showContents(final String result) {
        UiApplication.getUiApplication().invokeLater(new Runnable() 
        {

            public void run() 
            {
                _rtfOutput.setText(result);
            }
        });
    }
}
Back To Top

Send data using a FireAndForgetDestination object

  1. Import the required classes and interfaces.
    import net.rim.device.api.io.messaging.*;
    import net.rim.device.api.io.URI;
  2. Create a URI object to pass to the DestinationFactory class.
    URI uri = new URI("http://www.example.com");
  3. Create a FireAndForgetDestination object.
    FireAndForgetDestination ffd = null;
  4. Retrieve the FireAndForgetDestination object for your context, if one exists.
    try
    {
        ffd = (FireAndForgetDestination) DestinationFactory.getSenderDestination
                                              ("MyContext", uri);
  5. If no FireAndForgetDestination exists, create one.
        if(ffd == null)
        {
            ffd = DestinationFactory.createFireAndForgetDestination
                              (new Context("MyContext"), uri);
        }
  6. Create a ByteMessage object and populate it with information to send to a web service.
        ByteMessage myMsg = ffd.createByteMessage();
        myMsg.setStringPayload("I love my BlackBerry device!");
  7. Cast your message as an HTTPMessage to set the HTTP method that you want to use.
        ((HttpMessage) myMsg).setMethod(HttpMessage.POST);
  8. Send the message to the web service.
        ffd.sendNoResponse(myMsg);
  9. Catch any errors that occur if the message could not be sent for some reason.
        catch (Exception e)
        {
            // Process the error
        }
Back To Top
Previous topic: Communication API

Was this information helpful? Send us your comments.