I am using retrofit 2+ with gson library to fetch data from rest api. But whenever I try to run my app, it shows the following error:
"Expected BEGIN_ARRAY but was STRING at line 1 column 1 path $".
Hence I tried a lot to indentify the problem. Here is my code for json serializer. Json is given this way. In some cases some field is missing, for example title
is not included in all cases.
Api Data:
[
{
"_id": "fhfh49879787989",
"dn": "CN=9879798789",
"whenChanged": "20170704065349.0Z",
"name": "Student",
"mail": "student@mail.com",
"updated_at": "2017-07-04T18:22:43.624Z"
},
{
"_id": "595bdcf32c67a3f9ee6c2a25",
"dn": "CN=dsfdsfsdfsf",
"givenName": "Accounting Office",
"whenChanged": "20170801114732.0Z",
"name": "Accounting",
"mail": "accounting@mail.com",
"updated_at": "2017-07-04T18:22:43.641Z"
},
{
"_id": "584ab3b4122d13e1b0d1578d",
"dn": "CN=sfdfsfsdfl",
"sn": "Abels",
"title": "Student",
"givenName": "Gardrut",
"whenChanged": "20170807150844.0Z",
"department": "PMO",
"company": "Multi Lmited",
"name": "Mike Lizz",
"mail": "mail@yahoo.com",
"mobile": "+1321646498",
"updated_at": "2016-12-09T13:37:56.175Z"
},
{
"_id": "584ab3b3122d13e1b0d15735",
"dn": "CN=xdfsdfsfsdf",
"sn": "Acsdff",
"title": "Software Engineer",
"givenName": "Olin",
"whenChanged": "20170810064841.0Z",
"department": "Head",
"company": "Private limited",
"name": "James Oliver",
"mail": "mail@gmail.com",
"mobile": "+41228",
"updated_at": "2016-12-09T13:37:55.813Z"
},
....
]
POJO:
public class ColleagueModel implements Serializable {
@Expose
private String _id;
@Expose
private String dn;
@Expose
private String givenName;
@Expose
private String whenChanged;
@Expose
private String name;
@Expose
private String mail;
@Expose
private String updatedAt;
@Expose
private String sn;
@Expose
private String title;
@Expose
private String department;
@Expose
private String company;
@Expose
private String mobile;
// getter and setter...
My Service class:
public interface ColleagueApiService {
@GET("/api/users")
Call<List<ColleagueModel>> getAllColleagues();
}
Rest maneger class:
public class ColleagueRestManager {
public ColleagueApiService mColleagueService;
public ColleagueApiService getColleagueService() {
if (mColleagueService == null) {
Gson gson = new GsonBuilder()
.setLenient()
.serializeNulls()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.HTTP.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
mColleagueService = retrofit.create(ColleagueApiService.class);
}
return mColleagueService;
}
}
Adapter Class:
public class MyColleaguesAdapter extends RecyclerView.Adapter<MyColleaguesAdapter.ColleagueHolder> {
public static String TAG = MyColleaguesAdapter.class.getSimpleName();
private List<ColleagueModel> mColleague;
public MyColleaguesAdapter() {
mColleague = new ArrayList<>();
}
private List<MyColleagueModel> myColleagueModels;
public interface ColleagueListListener {
}
public void addColleague(ColleagueModel colleague) {
Log.d(TAG,colleague.getName());
mColleague.add(colleague);
notifyDataSetChanged();
}
// create new views (invoked by the layout manager)
@Override
public ColleagueHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflate a new colleague view
View view = LayoutInflater
.from(parent.getContext())
.inflate(R.layout.colleage_row_layout,parent,false);
return new ColleagueHolder(view);
}
@Override
public void onBindViewHolder(ColleagueHolder holder, int position) {
ColleagueModel currentColleague = mColleague.get(position);
holder.colleagueName.setText(currentColleague.getName());
holder.companyName.setText(currentColleague.getCompany());
holder.jobTitle.setText(currentColleague.getTitle());
}
@Override
public int getItemCount() {
return mColleague.size();
}
public class ColleagueHolder extends RecyclerView.ViewHolder{
public CardView cardView;
public ImageView colleaguePicture;
public TextView colleagueName;
public TextView companyName;
public TextView jobTitle;
public ColleagueHolder(View itemView) {
super(itemView);
colleaguePicture = itemView.findViewById(R.id.colleague_picture);
colleagueName = itemView.findViewById(R.id.colleague_name);
companyName = itemView.findViewById(R.id.company_name);
jobTitle = itemView.findViewById(R.id.job_title);
cardView = itemView.findViewById(R.id.cardview_user);
}
}
And Finally the Activity Class:
public class MyColleaguesPage extends AppCompatActivity {
private RecyclerView recyclerView;
private MyColleaguesAdapter adapter;
private Controller mController;
private ColleagueRestManager mManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mycolleagues_layout);
// Showing and Enabling clicks on the Home/Up button
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
configViews();
mManager = new ColleagueRestManager();
Call<List<ColleagueModel>> colleagueList = mManager.getColleagueService().getAllColleagues();
colleagueList.enqueue(new Callback<List<ColleagueModel>>() {
@Override
public void onResponse(Call<List<ColleagueModel>> call, Response<List<ColleagueModel>> response) {
if(response.isSuccessful()) {
List<ColleagueModel> colleagueList = response.body();
for (int i = 0; i < colleagueList.size(); i++) {
ColleagueModel colleague = colleagueList.get(i);
adapter.addColleague(colleague);
}
} else {
int sc = response.code();
switch (sc){
case 400:
Log.e("Error 400", "Bad Request");
break;
case 404:
Log.e("Error 404", "Not Found");
break;
default:
Log.e("Error", "Generic Error");
}
}
}
@Override
public void onFailure(Call<List<ColleagueModel>> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
Log.d("Error Message:"+"",t.getMessage());
}
})
}
private void configViews() {
recyclerView = this.findViewById(R.id.colleagues_recycler);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(MyColleaguesPage.this));
recyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
adapter = new MyColleaguesAdapter();
recyclerView.setAdapter(adapter);
}
}
Conastant class for getting api:
public class Constants {
public static final class HTTP {
public static final String BASE_URL = "https://app.com"; //not given the real url
}
public static final class DATABASE {
}
}
Edited Body
08-20 07:51:02.334 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: --> GET https://app.blu-pa.com/api/users http/1.1
08-20 07:51:02.334 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: --> END GET
08-20 07:51:02.377 1346-1367/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 860742 , only wrote 707760
08-20 07:51:02.383 1346-1366/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 707956 , only wrote 707760
08-20 07:51:02.386 3421-3426/demo.app.com.bluapp_client_and I/art: Do partial code cache collection, code=59KB, data=59KB
08-20 07:51:02.387 3421-3426/demo.app.com.bluapp_client_and I/art: After code cache collection, code=50KB, data=54KB
08-20 07:51:02.387 3421-3426/demo.app.com.bluapp_client_and I/art: Increasing code cache capacity to 256KB
08-20 07:51:02.392 3421-3440/demo.app.com.bluapp_client_and D/EGL_emulation: eglMakeCurrent: 0xa494e540: ver 2 0 (tinfo 0xa494d430)
08-20 07:51:02.404 1581-1601/? I/ActivityManager: Displayed demo.app.com.bluapp_client_and/.activity.myColleague.MyColleaguesPage: +83ms
08-20 07:51:02.657 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: <-- 200 https://app.blu-pa.com/login?callback=%2F (322ms)
08-20 07:51:02.657 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: x-dns-prefetch-control: off
08-20 07:51:02.657 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: x-frame-options: SAMEORIGIN
08-20 07:51:02.657 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: strict-transport-security: max-age=15552000; includeSubDomains
08-20 07:51:02.658 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: x-download-options: noopen
08-20 07:51:02.658 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: x-content-type-options: nosniff
08-20 07:51:02.658 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: x-xss-protection: 1; mode=block
08-20 07:51:02.658 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: set-cookie: language=de-DE; Max-Age=86400; Path=/; Expires=Mon, 21 Aug 2017 07:51:05 GMT
08-20 07:51:02.658 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: set-cookie: connect.sid=s%3Ah-1Pju1IRtwJwNG5VU5Ja0t1OPujcaHz.Bd6gMWB8Q3DtgOpP%2BHnMuh6QY5VGHwcChbOqTRVVee0; Path=/; HttpOnly
08-20 07:51:02.658 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: content-type: text/html; charset=utf-8
08-20 07:51:02.658 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: etag: W/"8af-hp6ns0Ui95kDbe9rVovQHfKz5pA"
08-20 07:51:02.658 3421-5002/demo.app.com.bluapp_client_and D/OkHttp: vary: Accept-Encoding