POST con Android Retrofit
Soy nuevo en la programación de Android y trabajo con Retrofit. He hecho un montón de investigaciones sobre este tema, pero no he podido encontrar una solución específica para mis necesidades. Estoy trabajando con nuestra API y tratando de hacer una solicitud POST. Logré esto con éxito con el siguiente código que no es de Retrofit:
private class ProcessLogin extends AsyncTask<Void, String, JSONObject> { private ProgressDialog pDialog; String email,password; protected void onPreExecute() { super.onPreExecute(); inputEmail = (EditText) findViewById(R.id.email); inputPassword = (EditText) findViewById(R.id.password); email = inputEmail.getText().toString(); password = inputPassword.getText().toString(); pDialog = new ProgressDialog(LoginActivity.this); pDialog.setTitle("Contacting Servers"); pDialog.setMessage("Logging in ..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } protected JSONObject doInBackground(Void... params) { HttpURLConnection connection; OutputStreamWriter request = null; URL url = null; String response = null; String parameters = "username="+email+"&password="+password; try { url = new URL("http://.../api/login"); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestMethod("POST"); request = new OutputStreamWriter(connection.getOutputStream()); request.write(parameters); request.flush(); request.close(); String line = ""; InputStreamReader isr = new InputStreamReader(connection.getInputStream()); BufferedReader reader = new BufferedReader(isr); StringBuilder sb = new StringBuilder(); while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } // Response from server after login process will be stored in response variable. response = sb.toString(); // You can perform UI operations here isr.close(); reader.close(); } catch(IOException e) { // Error } System.out.println(response); JSONObject jObj = null; // Try to parse the string to a JSON Object try { jObj = new JSONObject(response); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } // Return the JSONObject return jObj; } protected void onPostExecute(JSONObject json) { String status = (String) json.optJSONArray("users").optJSONObject(0).optJSONObject("user").optString("login"); pDialog.dismiss(); if (status.equals("Failed")) { loginMessage.setText("Login Failed"); } else if (status.equals("Success")) { loginMessage.setText("Success!"); startActivity(new Intent(getApplicationContext(), DActivity.class)); } } }
Ahora, estoy tratando de obtener los mismos resultados usando Retrofit, pero no estoy seguro de cómo recuperar el JSON de nuestro API usando Callbacks (estoy asumiendo que esta llamada debería suceder de forma asíncrona):
- Retrofit error de lanzamiento Se esperaba BEGIN_ARRAY pero era BEGIN_OBJECT
- Manejo de excepciones API en RxJava
- Android: Servicio de Intención con bibliotecas de red (Retrofit o Volley)
- Configuración de Android studio 1.1.0 minifyEnabled true causando problemas con la aplicación
- Cómo manejar la paginación en retrofit
He hecho una interfaz con el siguiente método:
@FormUrlEncoded @POST("/login") public void login(@Field("username") String username, @Field("password") String password, Callback<JSONObject> callback);
Y instanciado el RestAdapter, etc en el método onCreate de mi actividad. Cuando el usuario presiona el botón de "inicio de sesión" (después de introducir su nombre de usuario y contraseña), lo siguiente se llama dentro del método onClick del botón:
service.login(email, password, new Callback<JSONObject>() { @Override public void failure(final RetrofitError error) { android.util.Log.i("example", "Error, body: " + error.getBody().toString()); } @Override public void success(JSONObject arg0, Response arg1) { } } );
Esto no está funcionando como se pretende sin embargo, y realmente no creo que me estoy acercando a esto correctamente. Quiero ser capaz de hacer un POST a nuestro servidor, que envía de vuelta un bloque de datos con formato JSON sobre ese usuario. Si alguien pudiera señalarme en la dirección correcta, que sería muy apreciado. Gracias de antemano
- ¿Cómo utilizo el convertidor Gson en RetroFit?
- Cómo saber cuándo finaliza una llamada de Retrofit
- Cómo crear NTLM Authentification con Retrofit
- Java.lang.IllegalStateException: Se esperaba BEGIN_ARRAY pero era BEGIN_OBJECT en la línea 1 de la columna 2
- Cubriendo json array utilizando retrofit?
- AbstractMethodError cuando se utiliza RxJavaCallAdapterFactory en Retrofit 2
- Retrofit2.0 obtiene MalformedJsonException mientras el json parece correcto?
- Cómo cancelar la solicitud con retofit2 y RxAndroid
Uno de los beneficios de Retrofit no es tener que analizar el JSON usted mismo. Usted debe tener algo como:
service.login(email, password, new Callback<User>() { @Override public void failure(final RetrofitError error) { android.util.Log.i("example", "Error, body: " + error.getBody().toString()); } @Override public void success(User user, Response response) { // Do something with the User object returned } } );
Donde el User
es un POJO como
public class User { private String name; private String email; // ... etc. }
Y el JSON devuelto tiene campos que coinciden con la clase User
:
{ "name": "Bob User", "email": "[email protected]", ... }
Si necesita un análisis personalizado, el lugar para eso es cuando se configura el convertidor del adaptador REST con .setConverter (Convertidor) :
El convertidor utilizado para serialización y deserialización de objetos.
Seem Retrofit tiene problema con @POST
y @FormUrlEncoded
. Funciona bien si hacemos síncrono pero fallamos si es asíncrono.
Si el problema @mike es un objeto de deserialización, la clase User debe ser
public class User { @SerializedName("name") String name; @SerializedName("email") String email; }
Clase de interfaz
@FormUrlEncoded @POST("/login") void login(@Field("username") String username, @Field("password") String password, Callback<User> callback);
O
@FormUrlEncoded @POST("/login") void login(@Field("username") String username, @Field("password") String password, Callback<UserResponse> callback);
Dónde
public class UserResponse { @SerializedName("email") String email; @SerializedName("name") String name; }