Reputation: 414
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.
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.
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"
}
}
}
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
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
Reputation: 1
@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
Reputation: 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
Reputation: 1539
In your MainActivity.java
remove
User data = new User();
data = response.body();
and replace it with
User data = response.body();
Upvotes: 0
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
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