Tuesday, February 12, 2008

Basic Servlet Structure

Here's the outline of a basic servlet that handles GET requests. GET requests, for those unfamiliar with HTTP, are requests made by browsers when the user types in a URL on the address line, follows a link from a Web page, or makes an HTML form that does not specify a METHOD. Servlets can also very easily handle POST requests, which are generated when someone creates an HTML form that specifies METHOD="POST". We'll discuss that in later sections.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SomeServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

// Use "request" to read incoming HTTP headers (e.g. cookies)
// and HTML form data (e.g. data the user entered and submitted)


// Use "response" to specify the HTTP response line and headers
// (e.g. specifying the content type, setting cookies).


PrintWriter out = response.getWriter();
// Use "out" to send content to browser
}
}
(Download template source code -- click with the right mouse on the link or hold down SHIFT while clicking on the link.)

To be a servlet, a class should extend HttpServlet and override doGet or doPost (or both), depending on whether the data is being sent by GET or by POST. These methods take two arguments: an HttpServletRequest and an HttpServletResponse. The HttpServletRequest has methods that let you find out about incoming information such as FORM data, HTTP request headers, and the like. The HttpServletResponse has methods that lets you specify the HTTP response line (200, 404, etc.), response headers (Content-Type, Set-Cookie, etc.), and, most importantly, lets you obtain a PrintWriter used to send output back to the client. For simple servlets, most of the effort is spent in println statements that generate the desired page. Note that doGet and doPost throw two exceptions, so you are required to include them in the declaration. Also note that you have to import classes in java.io (for PrintWriter, etc.), javax.servlet (for HttpServlet, etc.), and javax.servlet.http (for HttpServletRequest and HttpServletResponse). Finally, note that doGet and doPost are called by the service method, and sometimes you may want to override service directly, e.g. for a servlet that handles both GET and POST request.

Wednesday, February 6, 2008

Bluecove Example

Remote Device Discovery

The LocalDevice class provides method 'getDiscoveryAgent' that returns an instance of the DiscoveryAgent. This DiscoveryAgent can then be used to discover remote bluetooth devices (start HCI inquiry).
import java.io.IOException;
import java.util.Vector;
import javax.bluetooth.*;

/**
* Minimal Device Discovery example.
*/
public class RemoteDeviceDiscovery {

public static final Vector/**/ devicesDiscovered = new Vector();

public static void main(String[] args) throws IOException, InterruptedException {

final Object inquiryCompletedEvent = new Object();

devicesDiscovered.clear();

DiscoveryListener listener = new DiscoveryListener() {

public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
System.out.println("Device " + btDevice.getBluetoothAddress() + " found");
devicesDiscovered.addElement(btDevice);
try {
System.out.println(" name " + btDevice.getFriendlyName(false));
} catch (IOException cantGetDeviceName) {
}
}

public void inquiryCompleted(int discType) {
System.out.println("Device Inquiry completed!");
synchronized(inquiryCompletedEvent){
inquiryCompletedEvent.notifyAll();
}
}

public void serviceSearchCompleted(int transID, int respCode) {
}

public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
}
};

synchronized(inquiryCompletedEvent) {
boolean started = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, listener);
if (started) {
System.out.println("wait for device inquiry to complete...");
inquiryCompletedEvent.wait();
System.out.println(devicesDiscovered.size() + " device(s) found");
}
}
}

}

Services Search

The following example shows how to use the DiscoveryAgent to find OBEX Push bluetooth service. Class from DeviceDiscovery example is used to find Bluetooth Devices.
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import javax.bluetooth.*;

/**
*
* Minimal Services Search example.
*/
public class ServicesSearch {

static final UUID OBEX_FILE_TRANSFER = new UUID(0x1106);

public static final Vector/**/ serviceFound = new Vector();

public static void main(String[] args) throws IOException, InterruptedException {

// First run RemoteDeviceDiscovery and use discoved device
RemoteDeviceDiscovery.main(null);

serviceFound.clear();

UUID serviceUUID = OBEX_OBJECT_PUSH;
if ((args != null) && (args.length > 0)) {
serviceUUID = new UUID(args[0], false);
}

final Object serviceSearchCompletedEvent = new Object();

DiscoveryListener listener = new DiscoveryListener() {

public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
}

public void inquiryCompleted(int discType) {
}

public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
for (int i = 0; i < servRecord.length; i++) {
String url = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
if (url == null) {
continue;
}
serviceFound.add(url);
DataElement serviceName = servRecord[i].getAttributeValue(0x0100);
if (serviceName != null) {
System.out.println("service " + serviceName.getValue() + " found " + url);
} else {
System.out.println("service found " + url);
}
}
}

public void serviceSearchCompleted(int transID, int respCode) {
System.out.println("service search completed!");
synchronized(serviceSearchCompletedEvent){
serviceSearchCompletedEvent.notifyAll();
}
}

};

UUID[] searchUuidSet = new UUID[] { serviceUUID };
int[] attrIDs = new int[] {
0x0100 // Service name
};

for(Enumeration en = RemoteDeviceDiscovery.devicesDiscovered.elements(); en.hasMoreElements(); ) {
RemoteDevice btDevice = (RemoteDevice)en.nextElement();

synchronized(serviceSearchCompletedEvent) {
System.out.println("search services on " + btDevice.getBluetoothAddress() + " " + btDevice.getFriendlyName(false));
LocalDevice.getLocalDevice().getDiscoveryAgent().searchServices(attrIDs, searchUuidSet, btDevice, listener);
serviceSearchCompletedEvent.wait();
}
}

}

}

OBEX Put Client

import java.io.IOException;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.obex.*;

public class ObexPutClient {

public static void main(String[] args) throws IOException, InterruptedException {

String serverURL = null; // = "btgoep://0019639C4007:6";
if ((args != null) && (args.length > 0)) {
serverURL = args[0];
}
if (serverURL == null) {
String[] searchArgs = null;
// Connect to OBEXPutServer from examples
// searchArgs = new String[] { "11111111111111111111111111111123" };
ServicesSearch.main(searchArgs);
if (ServicesSearch.serviceFound.size() == 0) {
System.out.println("OBEX service not found");
return;
}
// Select the first service found
serverURL = (String)ServicesSearch.serviceFound.elementAt(0);
}

System.out.println("Connecting to " + serverURL);

ClientSession clientSession = (ClientSession) Connector.open(serverURL);
HeaderSet hsConnectReply = clientSession.connect(null);
if (hsConnectReply.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
System.out.println("Failed to connect");
return;
}

HeaderSet hsOperation = clientSession.createHeaderSet();
hsOperation.setHeader(HeaderSet.NAME, "Hello.txt");
hsOperation.setHeader(HeaderSet.TYPE, "text");

//Create PUT Operation
Operation putOperation = clientSession.put(hsOperation);

// Send some text to server
byte data[] = "Hello world!".getBytes("iso-8859-1");
OutputStream os = putOperation.openOutputStream();
os.write(data);
os.close();

putOperation.close();

clientSession.disconnect(null);

clientSession.close();
}
}

OBEX Put Server

This class will start an OBEX service that will accept Put commands and print it to standard out.
import java.io.IOException;
import java.io.InputStream;

import javax.bluetooth.*;
import javax.microedition.io.Connector;
import javax.obex.*;

public class OBEXPutServer {

static final String serverUUID = "11111111111111111111111111111123";

public static void main(String[] args) throws IOException {

LocalDevice.getLocalDevice().setDiscoverable(DiscoveryAgent.GIAC);

SessionNotifier serverConnection = (SessionNotifier) Connector.open("btgoep://localhost:"
+ serverUUID + ";name=ObexExample");

int count = 0;
while(count < 2) {
RequestHandler handler = new RequestHandler();
serverConnection.acceptAndOpen(handler);
System.out.println("Received OBEX connection " + (++count));
}
}

private static class RequestHandler extends ServerRequestHandler {

public int onPut(Operation op) {
try {
HeaderSet hs = op.getReceivedHeaders();
String name = (String) hs.getHeader(HeaderSet.NAME);
if (name != null) {
System.out.println("put name:" + name);
}

InputStream is = op.openInputStream();

StringBuffer buf = new StringBuffer();
int data;
while ((data = is.read()) != -1) {
buf.append((char) data);
}

System.out.println("got:" + buf.toString());

op.close();
return ResponseCodes.OBEX_HTTP_OK;
} catch (IOException e) {
e.printStackTrace();
return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
}
}
}
}