studio - POST con la actualización de Android
cambiar titulo de layout android (2)
Parece que Retrofit tiene problemas con @POST
y @FormUrlEncoded
. Funciona bien si lo hacemos de forma síncrona pero falla si es asíncrono.
Si @mike problem es un objeto de deserialización, la clase User debería 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;
}
Soy nuevo en la programación de Android y estoy trabajando con Retrofit. He investigado mucho 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 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 nuestra API usando Callbacks (¿Supongo que esta llamada debería ocurrir de forma asíncrona?):
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);
E instaló RestAdapter, etc. en el método onCreate de mi actividad. Cuando el usuario presiona el botón "iniciar sesión" (después de ingresar su nombre de usuario y contraseña), se llama a lo siguiente 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) {
}
}
);
Sin embargo, esto no funciona como estaba previsto, y realmente no creo que me esté acercando a esto correctamente. Quiero poder realizar una POST a nuestro servidor, que envía un bloque de datos con formato JSON sobre ese usuario. Si alguien pudiera apuntarme en la dirección correcta, eso sería realmente apreciado. Gracias de antemano
Uno de los beneficios de Retrofit es no tener que analizar el JSON usted mismo. Deberías 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
public class User {
private String name;
private String email;
// ... etc.
}
y el JSON devuelto tiene campos que coinciden con la clase de User
:
{
"name": "Bob User",
"email": "[email protected]",
...
}
Si necesita un análisis personalizado, el lugar para eso es cuando configure el convertidor del adaptador REST con .setConverter (convertidor del convertidor) :
El convertidor utilizado para la serialización y deserialización de objetos.