mtrueblood
mtrueblood

Reputation: 414

Retrofit 2 - Getting 200 response but not getting data returned

TL;DR


New to retrofit so it's probably a noob mistake. Endpoint works fine in postman and I get Response{protocol=http/1.1, code=200, message=OK, url=http://192.168.1.249/api/v1/user/1} in the response but no data related to the user.

The Problem


I have built a REST API using Laravel that I want to access from devices. There will be many endpoints that need to be accessed but I can't get any of them to work. I am trying to get one working before adding the rest, but even though I get a 200 I am getting no data.

All of the properties are present on the response.body but they are all null.

The Code


MainActivity.java

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;


import com.x.tools.actualrest.rest.User;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.util.ArrayList;
import java.util.List;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends Activity {

    private CdenApi cdenAPI;

    private String token;

    String requested_with = "XMLHttpRequest";
    String content_type = "application/json";

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        createCdenAPI();

        cdenAPI.getUser(requested_with, content_type, "1").enqueue(userCallback);


    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    private void createCdenAPI() {
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(CdenApi.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

        cdenAPI = retrofit.create(CdenApi.class);
    }

    Callback<User> userCallback = new Callback<User>() {
        @Override
        public void onResponse(Call<User> call, Response<User> response) {
            if (response.isSuccessful()) {
                User data = new User();
                data = response.body();
            } else {

            }
        }

        @Override
        public void onFailure(Call<User> call, Throwable t) {
            t.printStackTrace();
        }
    };
} 

CdenApi.java

import com.x.tools.actualrest.rest.User;

import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Path;
import retrofit2.Call;

public interface CdenApi {

    String BASE_URL = "http://192.168.1.249/api/v1/";

    @GET("user/{id}")
    Call<User> getUser(@Header("X-Requested-With") String req_with, @Header("Content-Type") String cont_type, @Path("id")String userId);

} 

User.java

import com.google.gson.annotations.SerializedName;

public class User {

    @SerializedName("id")
    public Integer id;
    @SerializedName("name")
    public String name;
    @SerializedName("email")
    public String email;
    @SerializedName("access_level")
    public Integer accessLevel;
    @SerializedName("created_at")
    public String createdAt;
    @SerializedName("updated_at")
    public String updatedAt;
    @SerializedName("view_boxes")
    public ViewBoxes viewBoxes;

}

UserResult.java

import com.google.gson.annotations.SerializedName;

public class UserResult {

    @SerializedName("msg")
    public String msg;
    @SerializedName("user")
    public User user;

}

ViewBoxes.java

import com.google.gson.annotations.SerializedName;

public class ViewBoxes {

    @SerializedName("href")
    public String href;
    @SerializedName("method")
    public String method;

}

JSON from endpoint:

{
    "msg": "User information",
    "user": {
        "id": 1,
        "name": "Guy",
        "email": "[email protected]",
        "access_level": 1,
        "created_at": "2017-08-22 15:53:06",
        "updated_at": "2017-08-22 15:53:06",
        "view_boxes": {
            "href": "api/v1/user/1",
            "method": "GET"
        }
    }
}

The Solution


I need to know where I am going wrong. I am new to retrofit so I'm sure I have implemented something wrong but I can't see the issue.

Thanks in advance for any help.

Upvotes: 1

Views: 10757

Answers (6)

pstorli
pstorli

Reputation: 127

Concerning model classes, you can try to use the same model classes for the network, view and database access, but each has some quirks so it is better to have a generic model class that the db and network models can be converted to/from.

Concerning room and retrofit. Room seems to dislike lists of children and if retrofit gets a 200 (success) error code but no data, issue is probably that conversion process has failed and retrofit will not give you any info.

Try re-generating netwotrk model classes directly from json and use those. Android Studio plugin JsonToKotlinClass to create data classes ALT-K or right click package -> New -> Kotlin data class from JSON

Upvotes: 0

        @GET("/users")
        Call<ResponseBody> listRepos();//function to call api
    }

    RetrofitService service = retrofit.create(RetrofitService.class);
    Call<ResponseBody> result = service.listRepos(username);
    result.enqueue(new Callback<ResponseBody>() {

    @Override
    public void onResponse(Response<ResponseBody> response) {
        try {
            System.out.println(response.body().string());//convert reponse to string
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(Throwable t) {
        e.printStackTrace();
    }
});

Upvotes: -1



response.body().string();

//you get this 

  {
    "msg": "User information",
    "user": {
        "id": 1,
        "name": "Guy",
        "email": "[email protected]",
        "access_level": 1,
        "created_at": "2017-08-22 15:53:06",
        "updated_at": "2017-08-22 15:53:06",
        "view_boxes": {
            "href": "api/v1/user/1",
            "method": "GET"
        }
    }


//instead of this
 
Response{protocol=http/1.1,
 code=200, 
message=OK, 
url=http://192.168.1.249/api/v1/user/1}

Upvotes: -2

Nelson Katale
Nelson Katale

Reputation: 1539

In your MainActivity.java

remove

User data = new User();
data = response.body();

and replace it with

User data = response.body();

Upvotes: 0

joao86
joao86

Reputation: 2076

Try doing this

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    createCdenAPI();
    Response<User> response = cdenAPI.getUser(requested_with, content_type, "1").execute();

    User user = response.body();
 }

Upvotes: 1

Chris Gomez
Chris Gomez

Reputation: 6794

I think that the problem is that you have Call<User>, but as for your json you are getting UserResult in the response from the server, so instead it must be Call<UserResult> and in userCallback the same, instead of

Callback<User> userCallback = new Callback<User>

it must be

Callback<UserResult> userCallback = new Callback<UserResult>

and the same in the onresponse

public void onResponse(Call<UserResult> call, Response<UserResult> response) {
            if (response.isSuccessful()) {
                User data = new User();
                data = response.body().user;
            } else {

            }
        }

Upvotes: 7

Related Questions