A very disappointing feature of Retrofit 2.0 is that it does not exactly tell where it fails in parsing the response. Hence, In postman when I hit the request with same body, I get a login response as:
{
"result": "success",
"response_code": 200,
"data": {
"id": "1",
"display_name": "admin",
"email": "[email protected]",
"username": "admin",
"access_token": "8daa8e02ca432e51ae90912fbf63eeea"
}
}
But when I hit the exact same request with exactly the same body in Retrofit, I get a very peculiar response as: {protocol=http/1.1, code=200, message=OK, url=http://192.168.0.52/evidya/wp-api/v1/user/login}. Now I have gone through other related questions with above mentioned problem but none of them is working for me. Please Help. My code:
Retrofit API interface:
public interface eVidyaApi {
@FormUrlEncoded
@POST("user/login")
Call<LoginResponse> loginUser(
@HeaderMap Map<String, String> headers,
@Field("email") String email,
@Field("password") String password
);
}
Login Function:
public void login() {
Log.d(TAG, "Login");
if (!validate()) {
onLoginFailed();
return;
}
final ProgressDialog progressDialog = new ProgressDialog(LoginActivity.this, R.style.MyDialogTheme);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Authenticating...");
progressDialog.show();
String email = _emailText.getText().toString();
String password = _passwordText.getText().toString();
Log.d(TAG, "login: "+email+" "+password);
// TODO: Implement your own authentication logic here.
Call<LoginResponse> loginResponseCall = evidya.loginUser(Common.getHeaders(), email, password);
loginResponseCall.enqueue(new Callback<LoginResponse>() {
@Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
progressDialog.dismiss();
if(!response.isSuccessful()){
Toast.makeText(LoginActivity.this, ""+response.message(), Toast.LENGTH_SHORT).show();
Log.d(TAG, "onResponse: fail "+response.code());
return;
}
Log.d(TAG, "onResponse: success"+response.code()+" "+response);
if(response.body()!=null){
String content="";
// _loginButton.setEnabled(false);
LoginResponse loginResponse = response.body();
content += "code:"+ response.code();
content += "token:"+ loginResponse.getData().getAccessToken();
content += "result"+ loginResponse.getResult();
content += "result"+ loginResponse.getData().getDisplayName();
// onLoginSuccess();
Log.d(TAG, "onResponse: login res"+content);
} else {
Toast.makeText(LoginActivity.this, "Invalid response from server", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(LoginActivity.this, "Cannot fetch request", Toast.LENGTH_SHORT).show();
}
});
}
LoginResponse.java
package com.example.evidya.Retrofit.Model.LoginModel;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class LoginResponse {
@SerializedName("result")
@Expose
private String result;
@SerializedName("response_code")
@Expose
private Integer responseCode;
@SerializedName("data")
@Expose
private Data data;
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public Integer getResponseCode() {
return responseCode;
}
public void setResponseCode(Integer responseCode) {
this.responseCode = responseCode;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
}
Data.java
package com.example.evidya.Retrofit.Model.LoginModel;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Data {
@SerializedName("id")
@Expose
private String id;
@SerializedName("display_name")
@Expose
private String displayName;
@SerializedName("email")
@Expose
private String email;
@SerializedName("username")
@Expose
private String username;
@SerializedName("access_token")
@Expose
private String accessToken;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
}
My Logging(ok hhttp), when clicking the login button with wrong details:
My Logging(ok hhttp), when clicking the login button with CORRECT details:
Solution:
Basically the problem was that I was using Log.d(TAG, "onResponse: success"+response.code()+" "+response);
to check the response in the onresponse callback. Whereas all I should have done is to not get stuck there and check the value of the loginResponse object (from LoginResponse loginResponse = response.body();
). Because response.body actually stores the reponse in object form. This is how things work in retrofit.
As per your log, API calls properly. It also responds. but the issue is API authentication is failed from your back end. Add log on your web service and check. From the application side, it is working fine. this is not an issue of Retrofit.
Update your onResponse() with below and run application. then test and let me know what message you get.
if(response.body()!=null){
LoginResponse loginResponse = response.body();
String content="";
if (response.body().getResponseCode()==200){
content+= loginResponse.getData().getAccessToken();
content+= loginResponse.getData().getDisplayName();
content+= loginResponse.getData().getEmail();
content+= loginResponse.getData().getId();
content+= loginResponse.getData().getUsername();
}else{
content+=loginResponse.getData().getMsg();
}
Log.d(TAG, "onResponse: login res"+content);
} else {
Toast.makeText(LoginActivity.this, "Invalid response from server", Toast.LENGTH_SHORT).show();
}
Below code in Data.java
@SerializedName("msg")
@Expose
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With