Tuesday, July 6, 2010

Decoding PUT data

As we saw yesterday, for a HTTP PUT command the data arrives in the body of the HTML content. A simple way to read that data we saw was:

InputStream is = request.getInputStream();
char ch;
for (int i=0; i < request.getContentLength();i++){

    ch=(char)is.read();

    System.out.print(ch);

}

which will just read the data and send it to stdout. However want we want to do is get the data and use it as if it had been sent over as standard parameters. If you look at the data output from the above code you'll see it is sent as name value pairs delimited by & . So if we our data is being sent from the jquery ajax call as follows:

data: { Module: $('#Module').val(), Software: $('#Software').val()}

This will be encoded as (for example)

Module=ac31004&Software=SQL+Server

Notice that spaces have been encoded as + characters.

We need to decode this, turning the input into name value pairs which can be sent to our database update code. There's probably a lot of ways to do this, some more efficient than others, but we'll look at one way using a hashmap.

In your servlet code create a global hashmap variable (remember to import the util class import java.util.HashMap;) :

private HashMap hm = new HashMap();

Now in our servlet init method add objects that are going to represent the name of input fields in the original html form:

hm.put("Module", "");
hm.put("Software", "");

In our put method read the contents of the request body into a Byte array:

InputStream is = request.getInputStream();
byte Buffer[]= new byte [request.getContentLength()];
is.read(Buffer);

We can now split this into name value pairs by string tokenising on the & character:

StringTokenizer st = new StringTokenizer (input,"&");

We can no read through all these pairs and String tokenise on the "=" character. We can then assume that the first of the pair is the name and the second the value. Using the hashmap we created earlier, we can look to see if the name is in the hashmap and if it is replace the value with the one we've just got from the name value pair. Doing this we restrict the input to only those fields we defined in the init method when we set up the hashmap. Here's the code:

StringTokenizer st = new StringTokenizer (input,"&");
while (st.hasMoreTokens ()) {
   String inputPair=st.nextToken ();
   StringTokenizer st2 = new StringTokenizer (inputPair,"=");

    // First token should be name of input field
   String name=st2.nextToken();
   String var =st2.nextToken();
    if (hm.containsKey(name)){
      hm.put(name, var);

   }


Finally to use these values we can just get them from the hashmap.

String Software=(String)hm.get("Software");

No comments:

Post a Comment