jueves, 10 de octubre de 2013

Blog 4 Acceso desde Android a RESTFull

En la actualidad todas las capacidades servicios y funciones de cualquier computadora estan migrando hacia los SMARTPHONES. En este casio particular LOS SERVICIOS WEB con tecnologia RESTFull

1) Primero creamos un servicio normal desde Visual Studio en C# pero usaremos  “ASP.NET MVC 3 Web Application“, lo llamaremos “ServicioWebRest“.



2)  Elegimos la plantilla “Empty”

               


3)  Creamos  el servicio web de aparte del resto de la aplicación web. Llo primero que                     hacemos es añadir una nueva Area al proyecto, a la que llamaremos por ejemplo “Api“ .              nos queda una estructura asi :



4) Creamos Clase cliente

namespace ServicioWebRest.Areas.Api.Models
{
    public class Cliente
    {
        public int Id { get; set; }
        public string Nombre { get; set; }
        public int Telefono { get; set; }
    }
}

5) Creamos la clase Cliente Manager  con los siguientes métodos

·         Cliente ObtenerCliente(int id)
·         List<Clientes> ObtenerClientes()
·         bool InsertarCliente(Cliente c)
·         bool ActualizarCliente(Cliente c)
·         bool EliminarCliente(int id)

6) Los métodos  InsertarCliente  y List<Cliente> ObtenerClientes tendrán la siguiente codificación:

public bool InsertarCliente(Cliente cli)
{
      SqlConnection con = new SqlConnection(cadenaConexion);

      con.Open();

      string sql = "INSERT INTO Clientes (Nombre, Telefono) VALUES (@nombre, @telefono)";

      SqlCommand cmd = new SqlCommand(sql,con);

      cmd.Parameters.Add("@nombre", System.Data.SqlDbType.NVarChar).Value =       cli.Nombre;
      cmd.Parameters.Add("@telefono", System.Data.SqlDbType.Int).Value =         cli.Telefono;

      int res = cmd.ExecuteNonQuery();

      con.Close();

      return (res == 1);
}

public List<Cliente> ObtenerClientes()
{
      List<Cliente> lista = new List<Cliente>();

      SqlConnection con = new SqlConnection(cadenaConexion);

      con.Open();

      string sql = "SELECT IdCliente, Nombre, Telefono FROM Clientes";

      SqlCommand cmd = new SqlCommand(sql,con);

      SqlDataReader reader =
            cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);

      while (reader.Read())
      {
          Cliente cli = new Cliente();

          cli = new Cliente();
          cli.Id = reader.GetInt32(0);
          cli.Nombre = reader.GetString(1);
          cli.Telefono = reader.GetInt32(2);

          lista.Add(cli);
      }

      reader.Close();

      return lista;
}

 7)  Añadimos un ClientesController que contendra 2 acciones: la primera agestión               (insertar, eliminar etc ) Clientes() y la segunda a listar y Cliente().

* La acción Cliente()  tiene el siguiente código:


public JsonResult Cliente(int? id, Cliente item)
{
    switch (Request.HttpMethod)
    {
        case "POST":
            return Json(clientesManager.InsertarCliente(item));
        case "PUT":
            return Json(clientesManager.ActualizarCliente(item));
        case "GET":
            return Json(clientesManager.ObtenerCliente(id.GetValueOrDefault()),
                        JsonRequestBehavior.AllowGet);
        case "DELETE":
            return Json(clientesManager.EliminarCliente(id.GetValueOrDefault()));
    }

    return Json(new { Error = true, Message = "Operación HTTP desconocida" });
}

La acción Clientes() es muy sencilla, se limitará a llamar al método ObtenerClientes() y formatear los resultados como JSON (igual que el anterior)


[HttpGet]
public JsonResult Clientes()
{
    return Json(this.clientesManager.ObtenerClientes(),
                JsonRequestBehavior.AllowGet);
}

8) Existe dos tipos de URL. Una de ellas para acceder a la lista completa de cliente, y otra para realizar cualquier acción sobre un cliente en concreto:
·         Lista de clientes: http://servidor/Api/Clientes
·         Operación sobre cliente: http://servidor/Api/Clientes/Cliente/id_cliente

* Para la primera URL debemos registrarlos mediante el método MapRoute()dentro del método RegisterArea() que ya tendremos creado dentro de la claseApiAreaRegistration.

context.MapRoute(
    "AccesoClientes",
    "Api/Clientes",
    new
    {
        controller = "Clientes",
        action = "Clientes"
    }
);

* Para la segunda URL será muy similar, con la única diferencia de que ahora habrá una parte final variable que se corresponderá con el ID del cliente y que asignaremos al parámetro “id” de la acción.


context.MapRoute(
    "AccesoCliente",
    "Api/Clientes/Cliente/{id}",
    new
    {
        controller = "Clientes",
        action = "Cliente",
        id = UrlParameter.Optional
    }
);

 9)  La aplicación se compondrá de 5 botones, uno por cada una de las acciones que hemos implementado en el servicio web (insertar, actualizar, eliminar, recuperar un cliente, y listar todos los clientes).


10) Creamos un objeto HttpClient, que será el encargado de realizar la comunicación HTTP con el servidor a partir de los datos que nosotros le proporcionemos.







HttpClient httpClient = new DefaultHttpClient();

HttpPost post =

post.setHeader("content-type", "application/json");

11) Creamos el objeto JSON a incluir con la petición, que deberá contener los datos del nuevo cliente a insertar.

//Construimos el objeto cliente en formato JSON
JSONObject dato = new JSONObject();

dato.put("Nombre", txtNombre.getText().toString());
dato.put("Telefono", Integer.parseInt(txtTelefono.getText().toString()));

StringEntity entity = new StringEntity(dato.toString());
post.setEntity(entity);


12) Realizar la llamada al servicio mediante el método execute() del objeto HttpClient y recuperar el resultado mediante getEntity()


HttpResponse resp = httpClient.execute(post);
String respStr = EntityUtils.toString(resp.getEntity());

if(respStr.equals("true"))
    lblResultado.setText("Insertado OK.");

13) Hacemos la llamada al servicio mediante una tarea asíncrona, o AsynTask, que se ejecute en segundo plano.

private class TareaWSInsertar extends AsyncTask<String,Integer,Boolean> {

    protected Boolean doInBackground(String... params) {

        boolean resul = true;

        HttpClient httpClient = new DefaultHttpClient();

    HttpPost post = new
             HttpPost("http://10.0.2.2:2731/Api/Clientes/Cliente");

    post.setHeader("content-type", "application/json");

    try
        {
        //Construimos el objeto cliente en formato JSON
        JSONObject dato = new JSONObject();

        dato.put("Nombre", params[0]);
        dato.put("Telefono", Integer.parseInt(params[1]));

        StringEntity entity = new StringEntity(dato.toString());
        post.setEntity(entity);

                HttpResponse resp = httpClient.execute(post);
            String respStr = EntityUtils.toString(resp.getEntity());

            if(!respStr.equals("true"))
                resul = false;
        }
        catch(Exception ex)
        {
            Log.e("ServicioRest","Error!", ex);
            resul = false;
        }

        return resul;
    }

    protected void onPostExecute(Boolean result) {

        if (result)
        {
            lblResultado.setText("Insertado OK.");
        }
    }
}

* La llamada a la tarea asíncrona desde el evento onClick del botón de Insertar sería

btnInsertar.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        TareaWSInsertar tarea = new TareaWSInsertar();
        tarea.execute(
            txtNombre.getText().toString(),
            txtTelefono.getText().toString());
    }
});

14) Actualizar un cliente existente


HttpClient httpClient = new DefaultHttpClient();

HttpPut put = new HttpPut("http://10.0.2.2:2731/Api/Clientes/Cliente");
put.setHeader("content-type", "application/json");

try
{
    //Construimos el objeto cliente en formato JSON
    JSONObject dato = new JSONObject();

    dato.put("Id", Integer.parseInt(txtId.getText().toString()));
    dato.put("Nombre", txtNombre.getText().toString());
    dato.put("Telefono", Integer.parseInt(txtTelefono.getText().toString()));

    StringEntity entity = new StringEntity(dato.toString());
    put.setEntity(entity);

        HttpResponse resp = httpClient.execute(put);
        String respStr = EntityUtils.toString(resp.getEntity());

        if(respStr.equals("true"))
            lblResultado.setText("Actualizado OK.");
}
catch(Exception ex)
{
        Log.e("ServicioRest","Error!", ex);
}


15) Eliminación de un cliente

HttpClient httpClient = new DefaultHttpClient();

String id = txtId.getText().toString();

HttpDelete del =
    new HttpDelete("http://10.0.2.2:2731/Api/Clientes/Cliente/" + id);

del.setHeader("content-type", "application/json");

try
{
        HttpResponse resp = httpClient.execute(del);
        String respStr = EntityUtils.toString(resp.getEntity());

        if(respStr.equals("true"))
            lblResultado.setText("Eliminado OK.");
}
catch(Exception ex)
{
        Log.e("ServicioRest","Error!", ex);
}

16) Obtener un cliente



HttpClient httpClient = new DefaultHttpClient();

String id = txtId.getText().toString();

HttpGet del =
    new HttpGet("http://10.0.2.2:2731/Api/Clientes/Cliente/" + id);

del.setHeader("content-type", "application/json");

try
{
        HttpResponse resp = httpClient.execute(del);
        String respStr = EntityUtils.toString(resp.getEntity());

        JSONObject respJSON = new JSONObject(respStr);

        int idCli = respJSON.getInt("Id");
        String nombCli = respJSON.getString("Nombre");
        int telefCli = respJSON.getInt("Telefono");

        lblResultado.setText("" + idCli + "-" + nombCli + "-" + telefCli);
}
catch(Exception ex)
{
        Log.e("ServicioRest","Error!", ex);
}

17) Obtener listado completo de clientes

1

HttpClient httpClient = new DefaultHttpClient();

HttpGet del =
    new HttpGet("http://10.0.2.2:2731/Api/Clientes");

del.setHeader("content-type", "application/json");

try
{
        HttpResponse resp = httpClient.execute(del);
        String respStr = EntityUtils.toString(resp.getEntity());

        JSONArray respJSON = new JSONArray(respStr);

        String[] clientes = new String[respJSON.length()];

        for(int i=0; i<respJSON.length(); i++)
        {
            JSONObject obj = respJSON.getJSONObject(i);

            int idCli = obj.getInt("Id");
            String nombCli = obj.getString("Nombre");
            int telefCli = obj.getInt("Telefono");

            clientes[i] = "" + idCli + "-" + nombCli + "-" + telefCli;
        }

        //Rellenamos la lista con los resultados
        ArrayAdapter<String> adaptador =
                new ArrayAdapter<String>(ServicioWebRest.this,
                android.R.layout.simple_list_item_1, clientes);

    lstClientes.setAdapter(adaptador);
}
catch(Exception ex)
{
        Log.e("ServicioRest","Error!", ex);
}

EL RESULTADO SE DEBE VER ASI :