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
For a complete code sample, see "Code sample: Requesting data using a BlockingSenderDestination object".
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);
}
});
}
}
Request data using a NonBlockingSenderDestination object
For a complete code sample, see "Code sample: Request data using a NonBlockingSenderDestination object"
Implement the MessageListener interface
For a complete code sample, see "Code sample: Request data using a NonBlockingSenderDestination object"
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);
}
});
}
}