I am trying to login user and I am using Retrofit2 for networking but I am getting null response from the server though I have tested API in postman and it is showing response there but unable to fetch response in my app. I am unable to discover the cause of this error.
Here is an API URL. You can check response where email=digi#gmail.com and password=digi1234:
http://www.gurgaonhomeo.in/api_server/login
Below is my stack trace:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
This is my api response:
{
"data": [
{
"id": "7",
"username": null,
"mobile": "1254785698",
"email": "digi#gmail.com",
"image": "https://example.com",
"created_date": "2020-11-06",
"password": "dasdad324adad245435sffs34535",
"name": "Digi",
"address": "Hsbdbshbd",
"homoeo_practioner": "Yes"
}
],
"status": true,
"code": 200
}
These libraries I have used:
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
LoginRespose.java
public class LoginResponse {
#Expose
#SerializedName("code")
private String code;
#Expose
#SerializedName("data")
private List<LoginRes> data;
#Expose
#SerializedName("status")
private String status;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public List<LoginRes> getData() {
return data;
}
public void setData(List<LoginRes> data) {
this.data = data;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
LoginRes.java
public class LoginRes {
#SerializedName("address")
#Expose
private String address;
#SerializedName("created_date")
#Expose
private String createdDate;
#SerializedName("email")
#Expose
private String email;
#SerializedName("homoeo_practioner")
#Expose
private String homoeoPractioner;
#SerializedName("id")
#Expose
private String id;
#SerializedName("image")
#Expose
private String image;
#SerializedName("mobile")
#Expose
private String mobile;
#SerializedName("name")
#Expose
private String name;
#SerializedName("password")
#Expose
private String password;
#SerializedName("username")
#Expose
private String username;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getHomoeoPractioner() {
return homoeoPractioner;
}
public void setHomoeoPractioner(String homoeoPractioner) {
this.homoeoPractioner = homoeoPractioner;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
ApiService.java
#POST("login")
#FormUrlEncoded
Call<LoginResponse> logUser(#Field("email") String email,
#Field("password") String password);
Login.java
private void go(String mail,String pwd){
Retrofit retrofit = RetrofitClient.getInstance();
ApiService apiService = retrofit.create(ApiService.class);
apiService.logUser(mail,pwd).enqueue(new Callback<LoginResponse>() {
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if(response.isSuccessful()){
prg.dismiss();
List<LoginRes> res = response.body().getData();
Toast.makeText(getApplicationContext(),res.get(0).getEmail(),Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
prg.dismiss();
Toast.makeText(getApplicationContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
Why am I getting null response from the server?
First check if response.body() is null. Then check if the data inside response is null or []. Then if those requirements are filled, then take the list and show the toast.
Related
I am trying to get the value of a JSON response and display it in my textView and editText. But I get a null object reference as an error.
JSON Response:
{
"srNo": 1,
"date": "11/14/2019 12:00:00 AM",
"fieldEngineer": "Angel",
"accountName": "Forever 21 Megamall",
"irNo": 1,
"joNo": 1,
"address": "Mandaluyong City",
"contactPerson": "Jansen Babon",
"designation": "",
"contactNo": "",
"email": "",
"timeIn": "00:00:00",
"timeOut": "00:00:00",
"productType": "Security",
"problem": ""
}
Java class:
private void fetchData() {
JsonObject paramObject = new JsonObject();
Call<ResObj> call = userService.userLogin(paramObject);
call.enqueue(new Callback<ResObj>() {
#Override
public void onResponse(Call<ResObj> call, retrofit2.Response<ResObj> response) {
ResObj resObj = response.body();
String srNo = resObj.getSrNo();
String date = resObj.getDate();
String fieldEngineer = resObj.getFieldEngineer();
String accountName = resObj.getAccountName();
String irNo = resObj.getIrNo();
String joNo = resObj.getJoNo();
String address = resObj.getAddress();
String contactPerson = resObj.getContactPerson();
String designation = resObj.getDesignation();
String contactNo = resObj.getContactNo();
String email = resObj.getEmail();
String timeIn = resObj.getTimeIn();
String timeOut = resObj.getTimeOut();
String productType = resObj.getProductType();
String problem = resObj.getProblem();
//the response I am getting here is null
tvSrNo.setText(srNo);
etdate.setText(date);
etfieldengineer.setText(fieldEngineer);
etaccname.setText(accountName);
etirno.setText(irNo);
etjono.setText(joNo);
JsonObject workObj = new JsonObject();
try {
workObj.addProperty("srNo", resObj.getSrNo());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResObj> call, Throwable t) {
}
});
}
I tried using this tvSrNo.setText(resObj.getSrNo()) instead of tvSrNo.setText(srNo) but it still gets the same problem.
I am also using Retrofit.
I expect the result that JSON data will be placed in an editText or textView. But apparently, the response is getting null.
ResObj class:
private String date;
private String address;
private String accountName;
private String contactPerson;
private String timeOut;
private String problem;
private String srNo;
private String fieldEngineer;
private String joNo;
private String irNo;
private String message;
private String designation;
private String email;
private String timeIn;
private String productType;
private boolean status;
private String contactNo;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getContactPerson() {
return contactPerson;
}
public void setContactPerson(String contactPerson) {
this.contactPerson = contactPerson;
}
public String getTimeOut() {
return timeOut;
}
public void setTimeOut(String timeOut) {
this.timeOut = timeOut;
}
public String getProblem() {
return problem;
}
public void setProblem(String problem) {
this.problem = problem;
}
public String getSrNo() {
return srNo;
}
public void setSrNo(String srNo) {
this.srNo = srNo;
}
public String getFieldEngineer() {
return fieldEngineer;
}
public void setFieldEngineer(String fieldEngineer) {
this.fieldEngineer = fieldEngineer;
}
public String getJoNo() {
return joNo;
}
public void setJoNo(String joNo) {
this.joNo = joNo;
}
public String getIrNo() {
return irNo;
}
public void setIrNo(String irNo) {
this.irNo = irNo;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getTimeIn() {
return timeIn;
}
public void setTimeIn(String timeIn) {
this.timeIn = timeIn;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public String getContactNo() {
return contactNo;
}
public void setContactNo(String contactNo) {
this.contactNo = contactNo;
}
Logcat:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.android.ras.ResObj.getSrNo()' on a null object reference
at com.example.android.ras.MainActivity$3.onResponse(MainActivity.java:187)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:71)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
Change your String to Integer
public class Codebeautify {
private Integer srNo;
private String date;
private String fieldEngineer;
private String accountName;
private Integer irNo;
private Integer joNo;
private String address;
private String contactPerson;
private String designation;
private String contactNo;
private String email;
private String timeIn;
private String timeOut;
private String productType;
private String problem;
// Getter Methods
public Integer getSrNo() {
return srNo;
}
public String getDate() {
return date;
}
public String getFieldEngineer() {
return fieldEngineer;
}
public String getAccountName() {
return accountName;
}
public Integer getIrNo() {
return irNo;
}
public Integer getJoNo() {
return joNo;
}
public String getAddress() {
return address;
}
public String getContactPerson() {
return contactPerson;
}
public String getDesignation() {
return designation;
}
public String getContactNo() {
return contactNo;
}
public String getEmail() {
return email;
}
public String getTimeIn() {
return timeIn;
}
public String getTimeOut() {
return timeOut;
}
public String getProductType() {
return productType;
}
public String getProblem() {
return problem;
}
// Setter Methods
public void setSrNo(Integer srNo) {
this.srNo = srNo;
}
public void setDate(String date) {
this.date = date;
}
public void setFieldEngineer(String fieldEngineer) {
this.fieldEngineer = fieldEngineer;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public void setIrNo(Integer irNo) {
this.irNo = irNo;
}
public void setJoNo(Integer joNo) {
this.joNo = joNo;
}
public void setAddress(String address) {
this.address = address;
}
public void setContactPerson(String contactPerson) {
this.contactPerson = contactPerson;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public void setContactNo(String contactNo) {
this.contactNo = contactNo;
}
public void setEmail(String email) {
this.email = email;
}
public void setTimeIn(String timeIn) {
this.timeIn = timeIn;
}
public void setTimeOut(String timeOut) {
this.timeOut = timeOut;
}
public void setProductType(String productType) {
this.productType = productType;
}
public void setProblem(String problem) {
this.problem = problem;
}
}
Make your POJO class like this
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("srNo")
#Expose
private Integer srNo;
#SerializedName("date")
#Expose
private String date;
#SerializedName("fieldEngineer")
#Expose
private String fieldEngineer;
#SerializedName("accountName")
#Expose
private String accountName;
#SerializedName("irNo")
#Expose
private Integer irNo;
#SerializedName("joNo")
#Expose
private Integer joNo;
#SerializedName("address")
#Expose
private String address;
#SerializedName("contactPerson")
#Expose
private String contactPerson;
#SerializedName("designation")
#Expose
private String designation;
#SerializedName("contactNo")
#Expose
private String contactNo;
#SerializedName("email")
#Expose
private String email;
#SerializedName("timeIn")
#Expose
private String timeIn;
#SerializedName("timeOut")
#Expose
private String timeOut;
#SerializedName("productType")
#Expose
private String productType;
#SerializedName("problem")
#Expose
private String problem;
public Integer getSrNo() {
return srNo;
}
public void setSrNo(Integer srNo) {
this.srNo = srNo;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getFieldEngineer() {
return fieldEngineer;
}
public void setFieldEngineer(String fieldEngineer) {
this.fieldEngineer = fieldEngineer;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public Integer getIrNo() {
return irNo;
}
public void setIrNo(Integer irNo) {
this.irNo = irNo;
}
public Integer getJoNo() {
return joNo;
}
public void setJoNo(Integer joNo) {
this.joNo = joNo;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getContactPerson() {
return contactPerson;
}
public void setContactPerson(String contactPerson) {
this.contactPerson = contactPerson;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public String getContactNo() {
return contactNo;
}
public void setContactNo(String contactNo) {
this.contactNo = contactNo;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getTimeIn() {
return timeIn;
}
public void setTimeIn(String timeIn) {
this.timeIn = timeIn;
}
public String getTimeOut() {
return timeOut;
}
public void setTimeOut(String timeOut) {
this.timeOut = timeOut;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
public String getProblem() {
return problem;
}
public void setProblem(String problem) {
this.problem = problem;
}
}
make sure to have Gson Converter in your retrofit instance
private static Retrofit getRetrofitInstance() {
return new Retrofit.Builder()
.baseUrl(ROOT_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
then make call and put the data in ArrayList
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.android.ras.ResObj.getSrNo()' on a null object reference
Note: NullPointerException because you did not declare SrNo inside the model class
Try to use a jason to java class generator:
http://www.jsonschema2pojo.org/
Source type: JSON
Annotation style: Gson( if you used GSON) or none
Include getters and setters
public class Example {
private Integer srNo;
private String date;
private String fieldEngineer;
private String accountName;
private Integer irNo;
private Integer joNo;
private String address;
private String contactPerson;
private String designation;
private String contactNo;
private String email;
private String timeIn;
private String timeOut;
private String productType;
private String problem;
public Integer getSrNo() {
return srNo;
}
public void setSrNo(Integer srNo) {
this.srNo = srNo;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getFieldEngineer() {
return fieldEngineer;
}
public void setFieldEngineer(String fieldEngineer) {
this.fieldEngineer = fieldEngineer;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public Integer getIrNo() {
return irNo;
}
public void setIrNo(Integer irNo) {
this.irNo = irNo;
}
public Integer getJoNo() {
return joNo;
}
public void setJoNo(Integer joNo) {
this.joNo = joNo;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getContactPerson() {
return contactPerson;
}
public void setContactPerson(String contactPerson) {
this.contactPerson = contactPerson;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public String getContactNo() {
return contactNo;
}
public void setContactNo(String contactNo) {
this.contactNo = contactNo;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getTimeIn() {
return timeIn;
}
public void setTimeIn(String timeIn) {
this.timeIn = timeIn;
}
public String getTimeOut() {
return timeOut;
}
public void setTimeOut(String timeOut) {
this.timeOut = timeOut;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
public String getProblem() {
return problem;
}
public void setProblem(String problem) {
this.problem = problem;
}
}
first : Check response output,
you can Log.i or Toast it,,,
If your response not load or null ... - (the Problem in here)
Second : if respon Ok, Check your ResObj.getSrNo().
Print again... check
String srNo = resObj.getSrNo();
Log.i srNo... (problem or not)
Or checkyour Class Codebeautify
JsonObject paramObject = new JsonObject();
Call<ResObj> call = userService.userLogin(paramObject); // paramObject is empty object
You are passing empty JsonObject to your API parameter.
So you have to add parameter value to your paramObject. like this
try {
JsonObject paramObject = new JsonObject();
paramObject.addProperty("mobile", mobile);
// add other properties if you have
} catch (JSONException e) {
e.printStackTrace();
}
after that you should call your api like
Call<ResObj> call = userService.userLogin(paramObject);
As i am seeing the problem is in parsing, The retrofit can not mapping as your response is n't having ResObj as root.
{ "ResObj": { "srNo": 1, "date": "11/14/201912: 00: 00AM", "fieldEngineer": "Angel", "accountName": "Forever21Megamall", "irNo": 1, "joNo": 1, "address": "MandaluyongCity", "contactPerson": "JansenBabon", "designation": "", "contactNo": "", "email": "", "timeIn": "00: 00: 00", "timeOut": "00: 00: 00", "productType": "Security", "problem": "" } }
Modify your response or change your request
Call<JSONObject> call = userService.userLogin(paramObject);
Later in extract the values manually.
While working on retrofit, I used http://www.jsonschema2pojo.org this site to convert json to POJO. But I got an error while parsing JSON like this. Its saying Expected BEGIN_OBJECT but was BEGIN_ARRAY.
[
{
"uuid": "12e26270-b506-11e9-ad81-5f542bb63d66",
"first_name": "Nohar",
"last_name": "Kumar",
"title": "Premier League Player",
"gender": "N/A",
"date_of_birth": null,
"relationship_status": null,
"fav_quote": null,
"best_achievement": null,
"experience": null,
"skills": null,
"height": null,
"weight": null,
"about": null
}
]
Here is my modal class used for json to POJO.
public class UserAboutModel {
#SerializedName("uuid")
#Expose
private String uuid;
#SerializedName("first_name")
#Expose
private String firstName;
#SerializedName("last_name")
#Expose
private String lastName;
#SerializedName("title")
#Expose
private String title;
#SerializedName("gender")
#Expose
private String gender;
#SerializedName("date_of_birth")
#Expose
private String dateOfBirth;
#SerializedName("relationship_status")
#Expose
private String relationshipStatus;
#SerializedName("fav_quote")
#Expose
private String favQuote;
#SerializedName("best_achievement")
#Expose
private String bestAchievement;
#SerializedName("experience")
#Expose
private String experience;
#SerializedName("skills")
#Expose
private String skills;
#SerializedName("about")
#Expose
private String about;
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getRelationshipStatus() {
return relationshipStatus;
}
public void setRelationshipStatus(String relationshipStatus) {
this.relationshipStatus = relationshipStatus;
}
public String getFavQuote() {
return favQuote;
}
public void setFavQuote(String favQuote) {
this.favQuote = favQuote;
}
public String getBestAchievement() {
return bestAchievement;
}
public void setBestAchievement(String bestAchievement) {
this.bestAchievement = bestAchievement;
}
public String getExperience() {
return experience;
}
public void setExperience(String experience) {
this.experience = experience;
}
public String getSkills() {
return skills;
}
public void setSkills(String skills) {
this.skills = skills;
}
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
}
Here I am calling the method to get the response.
private void getUserAbout() {
apiInterface = APIClient.getClient().create(ApiInterface.class);
SharedPreferences sp = getSharedPreferences("UserData", Context.MODE_PRIVATE);
String token = sp.getString("User_Token", "");
Log.v("working", "working");
Call<UserAboutModel> call = apiInterface.userAboutBasic(currentUserUuid, "Bearer " + token);
call.enqueue(new Callback<UserAboutModel>() {
#Override
public void onResponse(Call<UserAboutModel> call, Response<UserAboutModel> response) {
if (response.isSuccessful()) {
String name = response.body().getFirstName() + " " + response.body().getLastName();
SharedPreferences pref = getSharedPreferences("UserAbout", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
Log.v("NAme", name);
Log.v("Title", response.body().getTitle());
editor.putString("UserName", name);
editor.putString("UserTitle", response.body().getTitle());
editor.putString("UserDOB", response.body().getDateOfBirth());
editor.putString("UserFAvQuote", response.body().getFavQuote());
editor.putString("UserSkill", response.body().getSkills());
editor.putString("UserGender", response.body().getGender());
editor.putString("UserRelationshipStatus", response.body().getRelationshipStatus());
editor.putString("UserExperience", response.body().getExperience());
editor.putString("UserBestAchievment", response.body().getBestAchievement());
editor.putString("UserCategory", primarySports.getText().toString());
editor.putString("UserSports", response.body().getExperience());
editor.apply();
} else {
try {
JSONObject jObjError = new JSONObject(response.errorBody().string());
Toast.makeText(getApplicationContext(), jObjError.getString("message"), Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onFailure(Call<UserAboutModel> call, Throwable t) {
call.cancel();
Log.d("TAG", t.toString());
}
});
}
And here is the log details
D/OkHttp: [{"uuid":"12e26270-b506-11e9-ad81-5f542bb63d66","first_name":"Nohar","last_name":"Kumar","title":"Premier League Player","gender":"N\/A","date_of_birth":null,"relationship_status":null,"fav_quote":null,"best_achievement":null,"experience":null,"skills":null,"height":null,"weight":null,"about":null}]
D/TAG: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
Can anyone help me out? How to solve this error?
The response that you are getting from the server is a list of UserAboutModel. However, in your code, you are expecting a single data. I think the function should look like the following.
public void onResponse(Call<UserAboutModel> call, Response<List<UserAboutModel>> response) {
// Now take the first element from the response list
// and then do the rest of your work
}
Instead of Response<UserAboutModel> use a Response<List<UserAboutModel>> so that it tells the function to expect a list of UserAboutModel.
Hope that helps!
I am consuming an API about cryptocurrency news called CryptoCompare.
My problem is that I can't detect what my code error is.
The error is as follows -> com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 70 path $.Data
I copy the Json and my two classes to help me find the solution.
Json:
{
"Type": 100,
"Message": "News list successfully returned",
"Promoted": [
],
"Data": [
{
"id": "2940487",
"guid": "https://cointelegraph.com/news/australian-hacker-pleads-guilty-to-stealing-450-000-in-xrp-last-year",
"published_on": 1566590880,
"imageurl": "https://images.cryptocompare.com/news/cointelegraph/dj0O90McM86.png",
"title": "Australian Hacker Pleads Guilty to Stealing $450,000 in XRP Last Year",
"url": "https://cointelegraph.com/news/australian-hacker-pleads-guilty-to-stealing-450-000-in-xrp-last-year",
"source": "cointelegraph",
"body": "An Australian woman has pleaded guilty to stealing $450,000 in XRP",
"tags": "Altcoin|Australia|Fraud|Hackers|XRP|Tokens|Police",
"categories": "XRP|ICO|Altcoin",
"upvotes": "0",
"downvotes": "0",
"lang": "EN",
"source_info": {
"name": "CoinTelegraph",
"lang": "EN",
"img": "https://images.cryptocompare.com/news/default/cointelegraph.png"
}
},
]
Link of Api -> https://min-api.cryptocompare.com/data/v2/news/?lang=EN
Java Class News:
public class News {
#SerializedName("Type")
#Expose
private Integer type;
#SerializedName("Message")
#Expose
private String message;
#SerializedName("Data")
#Expose
private List<Article> articles = null;
#SerializedName("HasWarning")
#Expose
private Boolean hasWarning;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
public Boolean getHasWarning() {
return hasWarning;
}
public void setHasWarning(Boolean hasWarning) {
this.hasWarning = hasWarning;
}
Java Class Article:
public class Article {
#SerializedName("id")
#Expose
private String id;
#SerializedName("guid")
#Expose
private String guid;
#SerializedName("published_on")
#Expose
private Integer publishedOn;
#SerializedName("imageurl")
#Expose
private String imageurl;
#SerializedName("title")
#Expose
private String title;
#SerializedName("url")
#Expose
private String url;
#SerializedName("source")
#Expose
private String source;
#SerializedName("body")
#Expose
private String body;
#SerializedName("tags")
#Expose
private String tags;
#SerializedName("categories")
#Expose
private String categories;
#SerializedName("upvotes")
#Expose
private String upvotes;
#SerializedName("downvotes")
#Expose
private String downvotes;
#SerializedName("lang")
#Expose
private String lang;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
public Integer getPublishedOn() {
return publishedOn;
}
public void setPublishedOn(Integer publishedOn) {
this.publishedOn = publishedOn;
}
public String getImageurl() {
return imageurl;
}
public void setImageurl(String imageurl) {
this.imageurl = imageurl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTags() {
return tags;
}
public void setTags(String tags) {
this.tags = tags;
}
public String getCategories() {
return categories;
}
public void setCategories(String categories) {
this.categories = categories;
}
public String getUpvotes() {
return upvotes;
}
public void setUpvotes(String upvotes) {
this.upvotes = upvotes;
}
public String getDownvotes() {
return downvotes;
}
public void setDownvotes(String downvotes) {
this.downvotes = downvotes;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
}
Interface to call Api:
public interface ApiInterface {
#GET("news")
Call<News> getNews(
#Query("lang") String lang,
#Query("api_key") String apiKey,
#Query("lTs") int lTs
);
Retrofit Class Builder
public static Retrofit getApiClient(String BASE_URL){
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.client(getUnsafeOkHttpClient().build())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
Fragment of Code when i call the api
private void LoadJson(){
swipeRefreshLayout.setRefreshing(true);
final ApiInterface apiInterface = ApiClient.getApiClient(ApiUtils.BASE_URL_NEWS).create(ApiInterface.class);
Call<News> call;
call = apiInterface.getNews("EN", ApiUtils.API_KEY,0);
call.enqueue(new Callback<News>() {
#Override
public void onResponse(Call<News> call, Response<News> response) {
if (response.isSuccessful() && response.body() != null){
articles.addAll(response.body().getArticles());
if (articles.size() - response.body().getArticles().size() == 0){
adapterNews.notifyDataSetChanged();
} else {
adapterNews.notifyItemRangeInserted(articles.size() - response.body().getArticles().size(), response.body().getArticles().size());
}
swipeRefreshLayout.setRefreshing(false);
progressBar.setVisibility(View.GONE);
} else {
Toast.makeText(getContext(), "No result", Toast.LENGTH_SHORT).show();
swipeRefreshLayout.setRefreshing(false);
progressBar.setVisibility(View.GONE);
}
}
#Override
public void onFailure(Call<News> call, Throwable t) {
Log.e(TAG, "ERROR API: " + t.getMessage() + " - " + t.getCause());
}
});
}
Any contribution is very helpful.
Thank you
FIXED THE PROBLEM WAS IN THE CALL
I notice that when you try query on api with wrong value like this
https://min-api.cryptocompare.com/data/v2/news/?lang=en
gives you json instead of array for data so this produce error
For fix and test instead of Locale.getDefault().getLanguage() use just "EN" and check the result
also for more help you can use this logging-interceptor
I am kinda of new to retrofit and i am not sure how to handle a nested json structure like this. if any one can help how to parse this type of structure . i would really i appreciate it . i have been stuck for days
{
"status": "ok",
"totalResults": 20,
"articles": [
{
"source": {
"id": null,
"name": "Bradenton.com"
},
"author": "By EILEEN NG Associated Press",
"title": "Malaysia says search for missing plane to end in June",
"description": "An official says the search for Malaysia Airlines Flight 370 by a U.S. company will likely end in June, as families of passengers marked the fourth anniversary of the plane's disappearance with hope that the world's biggest aviation mystery will be solved.",
"url": "http://www.bradenton.com/news/business/article203286984.html",
"urlToImage": "http://www.mcclatchy-wires.com/incoming/ukogzw/picture203286949/alternates/LANDSCAPE_1140/Malaysia_Missing_Plane_57970.jpg",
"publishedAt": "2018-03-03T09:42:00Z"
}
]
}
the http://www.jsonschema2pojo.org/ to convert your json to POJO and use that for retrofit 2.3
If you don't know how many classes you need to make ,just copy and paste your json here click here.
This will help you and make your work easy.
Create some pojos:
class Source {
String id;
String name;
}
class Article{
Source source;
String author;
String title;
String description;
String url;
String urlToImage;
String publishedAt;
}
class GetArticlesResponse{
String status;
int totalResults;
List<Article> articles;
}
And then pass GetArticlesResponse to your retrofit call.
import retrofit2.Response;
import retrofit2.Call;
public interface YourInterface {
#GET("your_end_point")
Call<Response<GetArticlesResponse>> getArticles();
}
or if you're using RX:
import retrofit2.Response;
import rx.Observable;
public interface YourInterface {
#GET("your_end_point")
Observable<Response<GetArticlesResponse>> getArticles();
}
MainClass.java
public class MainClass {
#SerializedName("status")
#Expose
private String status;
#SerializedName("totalResults")
#Expose
private Integer totalResults;
#SerializedName("articles")
#Expose
private List<Article> articles = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getTotalResults() {
return totalResults;
}
public void setTotalResults(Integer totalResults) {
this.totalResults = totalResults;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
}
Article.java
public class Article {
#SerializedName("source")
#Expose
private Source source;
#SerializedName("author")
#Expose
private String author;
#SerializedName("title")
#Expose
private String title;
#SerializedName("description")
#Expose
private String description;
#SerializedName("url")
#Expose
private String url;
#SerializedName("urlToImage")
#Expose
private String urlToImage;
#SerializedName("publishedAt")
#Expose
private String publishedAt;
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
}
Source.java
public class Source {
#SerializedName("id")
#Expose
private Object id;
#SerializedName("name")
#Expose
private String name;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Retrofit Interface
public interface YourInterface {
#GET("whatever api u are using")
Call<MainClass> getData(#Query("whatever key") String/int(whatever name)) //or leave blank
}
well when working with retrofit i suggest using Gson library with it which parses your json to an object type you should have created so first you should create an object representing your object from the response you get so it will be something like this in your case
public class Article implements Serializable {
private String author;
private String title;
private String description;
private String url;
private String urlToImage;
private String publishedAt;
private Source source;
public Story() {
}
public Story(String author,
String title,
Source source,
String description,
String url,
String urlToImage,
String publishedAt) {
this.author = author;
this.title = title;
this.source = source;
this.url = url;
this.urlToImage = urlToImage;
this.publishedAt = publishedAt;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
}
and similarly create your other class which is the Source class containing your Source object
public class Source implements Serializable {
private id id;
private String name;
public Source() {
}
public Source(int id,
String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
now in your retrofit api code you could do something like this
#GET("YOUR_ENDPOINT/")
Call<JsonObject> getArticles(... put your required fields here example ...#Query("token") String token);
and in your activity do something like this
List mArticleList = new ArrayList<>();
String mTotalResults = "";
UserApi service = ServiceGenerator.createService(UserApi.class);
Call<JsonObject> result = service.getArticles(token);
result.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.code() == 200) {
mArticleList = null;
JsonArray data = response.body().getAsJsonObject("data").getAsJsonArray("articles");
mArticleList = new Gson().fromJson(data.toString(), new TypeToken<List<Article>>(){}.getType());
mTotalResults = response.body().getAsJsonObject("data").getAsString("totalResults");
//if you want it as an integer you could do something like
int totalResults = Integer.parseInt(mTotalResults);
//... do what you want with your list
//...
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
//do what you have to do in case of error
}
});
}
hope this helps
I have the following JSON:
{
_id: "5252fdf424f1e7fbf7000004",
address: "Calle 1000",
city: "ConcepciĆ³n",
created_at: "2013-10-07T18:31:19.375Z",
description: "",
name: "Joctos",
phone: "94967994",
updated_at: "2013-12-09T13:03:07.328Z",
happy_hour: {
active: false,
type: 1,
all_day: false,
start: "2013-12-17T03:30:00.000Z",
end: "2013-12-17T05:00:00.000Z"
}
}
Tell them to receive and work with JSON GSON me to believe an object, the probleam is that defined the object follows
public class StoreModel {
#SerializedName("_id")
private String _id;
#SerializedName("address")
private String address;
#SerializedName("city")
private String city;
#SerializedName("created_at")
private String created_at;
#SerializedName("description")
private String description;
#SerializedName("name")
private String name;
#SerializedName("phone")
private String phone;
#SerializedName("updated_at")
private String updated_at;
public String get_id() {
return this._id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public String getCreated_at() {
return this.created_at;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getUpdated_at() {
return this.updated_at;
}
public void setUpdated_at(String updated_at) {
this.updated_at = updated_at;
}
}
How should I define my model to get the "happy_hours" data?
StoreModel class will contain the object of happy_hours
Create a HappyHours class with appropriate attributes and add an attribute happyHours to your StoreModel :
#SerializedName("happy_hours")
private HappyHours happyHours;
For Date objects try "Date start;" and "Date end;"
If it doesn't work, you have to write an adapter :
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Date.class, new DateGsonDeserializer());
gsonBuilder.create();
public class DateGsonDeserializer implements JsonDeserializer<Date> {
#Override
public Date deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) throws JsonParseException {
// just write the right formatter from SimpleDateFormat
return formatToDate(jsonElement.getAsString())
}
}