1

Good day,

I know this question has been asked and the other two topics I found did help up until a point. I have a response from the client that I do not have control over so the format it comes through is what I need to work with.

The Json contains a list of user info from multiple users. That is the reason I was using a List instead of a POJO. The issue is as follows. the POJO does return without any errors but also without any values and only one value instead of more than one

So what I gather is that the JSON is in a format where it is not seen as a list but an object.

Using POSTMAN as a benchmark tool to verify if the GET call work the values return in list

I am still a noob in this area so any help will be appreciated.

The JASON response from postman looks as follow(That is where I realised the way its being retrieved might be seen as object and not a list.

{
  "items": [
   {
    "userpassword": "TEST123",
    "userstatus": "A",
    "useremail": "Someperson@domain.com",
    "firstname": "Some",
    "lastname": "Person"
},
{
    "userpassword": "Pass123@",
    "userstatus": "C",
    "useremail": "personannom@domain.org",
    "firstname": "Annom",
    "lastname": "Person`"
},
{
    "userpassword": "PietIE2#3",
    "userstatus": "A",
    "useremail": "Piet@pieinthesky.co.uk",
    "firstname": "Piet",
    "lastname": "Pompies"
},

],....
}

So it seems that I need to drill in one more level to get to the values.

Just some more examples

My Interface class:

import retrofit2.Call;
import retrofit2.http.GET;


public interface JasonPlaceHolder {



    @GET("allusers")
    Call<UserInfo> getUserInfo();"
    //Call<List<UserInfo>> getUserInfo();  WAS
}

My class to store the information in

public class UserInfo {

    private String userpassword;

    private String userstatus;

    private String useremail;

    private String firstname;

    private String lastname;


    public String getUserpassword() {
    return userpassword;
    }

    public String getUserstatus() {
    return userstatus;
    }

    public String getUseremail() {
    return useremail;
    }

    public String getFirstname() {
    return firstname;
    }

    public String getLastname() {
    return lastname;
    }
}

And then my call in the mainactivity class (Because its not a list anymore I cannot loop through the records anymore

Retrofit retrofit = new Retrofit.Builder().
  baseUrl("http://10..../com/").
  addConverterFactory(GsonConverterFactory.create()).
  build();

JasonPlaceHolder jasonPlaceHolderApi = retrofit.create(JasonPlaceHolder.class);

Call<UserInfo> call = jasonPlaceHolderApi.getUserInfo();
  call.enqueue(new Callback<UserInfo>() {
   @Override
    public void onResponse(Call<UserInfo> call, Response<UserInfo> response) {

     if(!response.isSuccessful()){
      textVierResults.setText("code: " + response.code());
     return;
  }
  UserInfo userInfos = response.body();

  //for(UserInfo ui:userInfos){
  String content = "";
  content += "Useremail: "    + userInfos.getUseremail()    + "\n";
  content += "Userpassword: " + userInfos.getUserpassword() + "\n";
  content += "Firstname: "    + userInfos.getFirstname()    + "\n";
  content += "Lastname: "     + userInfos.getLastname()     + "\n";
  content += "Userstatus: "   + userInfos.getUserstatus()   + "\n";

  textVierResults.append(content);

  // }


}



     @Override
      public void onFailure(Call<UserInfo> call, Throwable t) {
      Toast.makeText(MainActivity.this, "An error occurred", Toast.LENGTH_SHORT).show();
      textVierResults.setText(t.getMessage());
      }
      });

Could anybody suggest a solution.

Sailendra
  • 1,318
  • 14
  • 29
RPN
  • 31
  • 1
  • 5
  • 1
    Does this answer your question? [Retrofit2 Android: Expected BEGIN\_ARRAY but was BEGIN\_OBJECT at line 1 column 2 path $](https://stackoverflow.com/questions/36177629/retrofit2-android-expected-begin-array-but-was-begin-object-at-line-1-column-2) – Saurabh Thorat Dec 13 '19 at 08:19

5 Answers5

0

So it seems that I need to drill in one more level to get to the values.

You're probably right, you might need something like this now:

class SomeClass {

   ArrayList<UserInfo> info;
}

And now you catch your response into this.

SkypeDogg
  • 1,000
  • 2
  • 13
  • 28
0

create new model class Items pass replace it with UserInfo passed JasonPlaceHolder and Retrofit class

public class Items{
List<UserInfo> items;

   public list<UserInfo> getitems() {
    return items;
    }

}





call.enqueue(new Callback<Items>() {
   @Override
    public void onResponse(Call<Items> call, Response<Items> response) {

     if(!response.isSuccessful()){
      textVierResults.setText("code: " + response.getitems());
     return;
  }
Jai Khambhayta
  • 4,198
  • 2
  • 22
  • 29
  • Do I still need to execute the two command "JasonPlaceHolder jasonPlaceHolderApi = retrofit.create(JasonPlaceHolder.class); Call> call = jasonPlaceHolderApi.getUserInfo();" To start the "call.enqeue" function – RPN Dec 13 '19 at 10:11
  • @GET("allusers") Call getUserInfo();" //Call getUserInfo(); WAS // replace this with old one – Jai Khambhayta Dec 13 '19 at 10:15
0

If you want to parse the json data manually to get to the list node in the json tree,

Add a JSONResponse class which will represent the raw JSON returned and you can get the userInfos Array using the getItems method which will return the value of the 'items' key in the Json object (In this case, would return an array of UserInfo objects)

public class JSONResponse {
private UserInfo[] items;

public UserInfo[] getItems() {
    return items;
}

}

make Get method return a JSONResponse object like below

@GET("allusers")
Call<JSONResponse> getUserInfo();"

Then finally, in onResponse, get the list of UserInfo from the JSONResponse object like below

JSONResponse jsonResponse = response.body();
userInfos= new ArrayList<>(Arrays.asList(jsonResponse.getItems()));
 String content = "";

for(UserInfo ui:userInfos){
content += "Useremail: "    + ui.getUseremail()    + "\n";
content += "Userpassword: " + ui.getUserpassword() + "\n";
content += "Firstname: "    + ui.getFirstname()    + "\n";
content += "Lastname: "     + ui.getLastname()     + "\n";
content += "Userstatus: "   + ui.getUserstatus()   + "\n";


}
textVierResults.append(content);
Oluwasegun Wahaab
  • 2,663
  • 3
  • 16
  • 19
0

First thing your response start with { it means it is an object and that object contain list its name is items .There will be one root main class which contain the list .

So create UserInfoRoot class

  class UserInfoRoot {
@SerializedName("items")
@Expose
private List<UserInfo > userInfo = null;

public List<UserInfo > getUserInfo () {
    return userInfo ;
}

public void setUserInfo(List<UserInfo > userInfo ) {
   this.userInfo = userInfo ;
 }  
 }   

Now replace UserInfo with UserInfoRoot Call<UserInfoRoot> getUserInfo();

Rahul sharma
  • 1,492
  • 12
  • 26
0

try as below,

public class UserInfo {

    private String userpassword;
    private String userstatus;
    private String useremail;
    private String firstname;
    private String lastname;


    public String getUserpassword() {
        return userpassword;
    }

    public String getUserstatus() {
        return userstatus;
    }

    public String getUseremail() {
        return useremail;
    }

    public String getFirstname() {
        return firstname;
    }

    public String getLastname() {
        return lastname;
    }
}

and create a response model inluding attribute of name "items",

class responseUserInfor{
    private List<UserInfo> items;

    public List<UserInfo> getItems() {
        return items;
    }

    public void setItems(List<UserInfo> items) {
        this.items = items;
    }
}

and change the place holder class as below.

import retrofit2.Call;
import retrofit2.http.GET;

public interface JasonPlaceHolder {
    @GET("allusers")
    Call<responseUserInfor> getUserInfo();"
    //Call<List<UserInfo>> getUserInfo();  WAS
}