POST с Android Retrofit
Я новичок в программировании на Android и работаю с Retrofit. Я провел кучу исследований по этой теме, но не смог найти решение, соответствующее моим потребностям. Я работаю с нашим API и пытаюсь сделать запрос POST. Я успешно достиг этого с помощью следующего кода без возможности восстановления:
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));
}
}
}
Теперь я пытаюсь получить те же результаты с помощью Retrofit, но я не уверен, как вернуть JSON из нашего API с помощью Callbacks (я предполагаю, что этот вызов должен происходить асинхронно?):
Я создал интерфейс со следующим методом:
@FormUrlEncoded
@POST("/login")
public void login(@Field("username") String username, @Field("password") String password, Callback<JSONObject> callback);
И создал экземпляр RestAdapter и т.д. в моем методе onCreate. Когда пользователь нажимает кнопку "login" (после ввода имени пользователя и пароля), внутри метода onClick вызывается следующее:
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) {
}
}
);
Это не работает, как предполагалось, и я действительно не думаю, что я правильно подхожу к этому. Я хочу, чтобы сделать POST на нашем сервере, который отправляет обратно блок данных формата JSON об этом пользователе. Если бы кто-нибудь мог указать мне в правильном направлении, это было бы действительно оценено. Заранее благодарю
Ответы
Ответ 1
Одним из преимуществ Retrofit является отсутствие необходимости самостоятельно разбирать JSON. У вас должно быть что-то вроде:
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
}
}
);
Где User
- POJO, как
public class User {
private String name;
private String email;
// ... etc.
}
а возвращаемый JSON имеет поля, соответствующие классу User
:
{
"name": "Bob User",
"email": "[email protected]",
...
}
Если вам нужен индивидуальный синтаксический анализ, это место, когда вы устанавливаете конвертер адаптера REST с помощью . setConverter (конвертер конвертера):
Преобразователь, используемый для сериализации и десериализации объектов.
Ответ 2
Seem Retrofit имеет проблемы с @POST
и @FormUrlEncoded
. Он работает хорошо, если мы выполняем синхронный, но сбой, если он асинхронен.
Если проблема @mike является объектом десериализации, класс пользователя должен быть
public class User {
@SerializedName("name")
String name;
@SerializedName("email")
String email;
}
Класс интерфейса
@FormUrlEncoded
@POST("/login")
void login(@Field("username") String username, @Field("password") String password, Callback<User> callback);
или
@FormUrlEncoded
@POST("/login")
void login(@Field("username") String username, @Field("password") String password, Callback<UserResponse> callback);
Где
public class UserResponse {
@SerializedName("email")
String email;
@SerializedName("name")
String name;
}