Tuesday, 29 January 2013

Handling HTTP POST method in Android

Hello Androidies… :-) Today I am going to talk about handling HTTP POST method in an Android program. This is little bit relate to my previous post which I have explained the same scenario for GET method. POST method is more secure when we transfer confidential data to a different location by using HTTP. The reason is the content goes inside the body, not with the header as in GET method.
Let me explain the scenario that I am going to accomplish with this blog post. I want to send some confidential data to a different server by using one of my native Android application. In the server side there is a PHP page listen to the parameters that I am passing and grab relevant data.
This is the UI (User Interface) part for this project.
HTTP POST method in Android
Figure 1
Actually, giving a username and a password is something additional when we concern about our main requirement. Our main requirement is sending a request to a web page by using HTTP POST method and listen to the response if it succeed. Additionally what I have done here is, prompting a Toast message if we get a response. Figure 2 shows the possible Toast messages that you will get. But understand clearly, that is NOT the response we get from the server. That is something we hard code in our program to show for the user, after getting the response.
HTTP POST method in Android
Figure 2
Are we ready to dive in to the source code :D Don’t forget to copy the code in to an IDE and read the comments, because I have explained the logic in the code and I am not going to repeat it here again.
package com.anuja.httppost;

/**
 * @author AnujAroshA
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MyHttpPostProjectActivity extends Activity implements OnClickListener {

 private EditText usernameEditText;
 private EditText passwordEditText;
 private Button sendPostReqButton;
 private Button clearButton;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);

        usernameEditText = (EditText) findViewById(R.id.login_username_editText);
        passwordEditText = (EditText) findViewById(R.id.login_password_editText);

        sendPostReqButton = (Button) findViewById(R.id.login_sendPostReq_button);
        sendPostReqButton.setOnClickListener(this);

        clearButton = (Button) findViewById(R.id.login_clear_button);
        clearButton.setOnClickListener(this);        
    }

 @Override
 public void onClick(View v) {

  if(v.getId() == R.id.login_clear_button){
   usernameEditText.setText("");
   passwordEditText.setText("");
   passwordEditText.setCursorVisible(false);
   passwordEditText.setFocusable(false);
   usernameEditText.setCursorVisible(true);
   passwordEditText.setFocusable(true);
  }else if(v.getId() == R.id.login_sendPostReq_button){
   String givenUsername = usernameEditText.getEditableText().toString();
   String givenPassword = passwordEditText.getEditableText().toString();

   System.out.println("Given username :" + givenUsername + " Given password :" + givenPassword);

   sendPostRequest(givenUsername, givenPassword);
  } 
 }

 private void sendPostRequest(String givenUsername, String givenPassword) {

  class SendPostReqAsyncTask extends AsyncTask<String, Void, String>{

   @Override
   protected String doInBackground(String... params) {

    String paramUsername = params[0];
    String paramPassword = params[1];

    System.out.println("*** doInBackground ** paramUsername " + paramUsername + " paramPassword :" + paramPassword);

    HttpClient httpClient = new DefaultHttpClient();

    // In a POST request, we don't pass the values in the URL.
    //Therefore we use only the web page URL as the parameter of the HttpPost argument
    HttpPost httpPost = new HttpPost("http://www.nirmana.lk/hec/android/postLogin.php");

    // Because we are not passing values over the URL, we should have a mechanism to pass the values that can be
    //uniquely separate by the other end.
    //To achieve that we use BasicNameValuePair    
    //Things we need to pass with the POST request
    BasicNameValuePair usernameBasicNameValuePair = new BasicNameValuePair("paramUsername", paramUsername);
    BasicNameValuePair passwordBasicNameValuePAir = new BasicNameValuePair("paramPassword", paramPassword);

    // We add the content that we want to pass with the POST request to as name-value pairs
    //Now we put those sending details to an ArrayList with type safe of NameValuePair
    List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
    nameValuePairList.add(usernameBasicNameValuePair);
    nameValuePairList.add(passwordBasicNameValuePAir);

    try {
     // UrlEncodedFormEntity is an entity composed of a list of url-encoded pairs. 
     //This is typically useful while sending an HTTP POST request. 
     UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairList);

     // setEntity() hands the entity (here it is urlEncodedFormEntity) to the request.
     httpPost.setEntity(urlEncodedFormEntity);

     try {
      // HttpResponse is an interface just like HttpPost.
      //Therefore we can't initialize them
      HttpResponse httpResponse = httpClient.execute(httpPost);

      // According to the JAVA API, InputStream constructor do nothing. 
      //So we can't initialize InputStream although it is not an interface
      InputStream inputStream = httpResponse.getEntity().getContent();

      InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

      BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

      StringBuilder stringBuilder = new StringBuilder();

      String bufferedStrChunk = null;

      while((bufferedStrChunk = bufferedReader.readLine()) != null){
       stringBuilder.append(bufferedStrChunk);
      }

      return stringBuilder.toString();

     } catch (ClientProtocolException cpe) {
      System.out.println("First Exception caz of HttpResponese :" + cpe);
      cpe.printStackTrace();
     } catch (IOException ioe) {
      System.out.println("Second Exception caz of HttpResponse :" + ioe);
      ioe.printStackTrace();
     }

    } catch (UnsupportedEncodingException uee) {
     System.out.println("An Exception given because of UrlEncodedFormEntity argument :" + uee);
     uee.printStackTrace();
    }

    return null;
   }

   @Override
   protected void onPostExecute(String result) {
    super.onPostExecute(result);

    if(result.equals("working")){
     Toast.makeText(getApplicationContext(), "HTTP POST is working...", Toast.LENGTH_LONG).show();
    }else{
     Toast.makeText(getApplicationContext(), "Invalid POST req...", Toast.LENGTH_LONG).show();
    }
   }   
  }

  SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();
  sendPostReqAsyncTask.execute(givenUsername, givenPassword);  
 }
}
Compare above code set with the HTTP GET method code set that I have posted in my previous post. Then you will get a clear idea about what I have changed, where I have changed and why I have changed that code set. Don’t forget to see the differences in the PHP pages also ;-)
<?php

$varUsername = $_POST['paramUsername'];
$varPassword = $_POST['paramPassword'];

if($varUsername == "anuja" && $varPassword == "123"){
 echo 'working';
}else{
 echo 'invalid';
}

?>
Now time for wrap-up. Thanks “Nirman” for hosting my “postLogin.php”.
Let’s meet with something different in next time :-)

No comments:

Post a Comment