Reputation: 568
I'm using Retrofit to comunicate with REST API on Android, but I getting an error NullPointerException like below. I try using postman, the API is work fine and I get the response.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List ukmutilizer.project.com.ukm_utilizer.model.CheckEmail.getData()' on a null object reference
This my Activity class
private void sendRequest(String checkEmail){
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<CheckEmail> call = apiService.getEmailStatus(checkEmail);
call.enqueue(new Callback<CheckEmail>() {
@Override
public void onResponse(Call<CheckEmail> call, Response<CheckEmail> response) {
CheckEmailData emailDataList = response.body().getData();
Log.d("Numer of Data : ", String.valueOf(response.body().getData()));
}
@Override
public void onFailure(Call<CheckEmail> call, Throwable t) {
Toast.makeText(CheckEmailPage.this, "Something went wrong!", Toast.LENGTH_SHORT).show();
Log.e("Error Retrofit : ", String.valueOf(t));
}
});
this is the ApiInterface
public interface ApiInterface {
@POST("users/check_status")
Call<CheckEmail> getEmailStatus(@Body String email);
}
this is the retrofit instance
`public class ApiClient {
public static final String BASE_URL = "https://f49d9d29-8471-4126-95b0-1ec3d18eda94.mock.pstmn.io/v1/";
private static Retrofit retrofit = null;
public static Retrofit getClient(){
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(logging).build();
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}`
and this is the json response
{
"code": 1000,
"message": "OK",
"data": {
"id": "1",
"email": "[email protected]",
"status": "1",
"name": "test",
"category": "2"
}
}
this is the POJO
`public class CheckEmail {
@SerializedName("code")
@Expose
private Integer code;
@SerializedName("message")
@Expose
private String message;
@SerializedName("data")
@Expose
private CheckEmailData data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public CheckEmailData getData() {
return data;
}
public void setData(CheckEmailData data) {
this.data = data;
}
}`
CheckEmailData POJO
`public class CheckEmailData {
@SerializedName("id")
@Expose
private String id;
@SerializedName("email")
@Expose
private String email;
@SerializedName("status")
@Expose
private String status;
@SerializedName("name")
@Expose
private String name;
@SerializedName("category")
@Expose
private String category;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}`
Upvotes: 2
Views: 2043
Reputation: 568
I've been solved the problem
I was add the headers on interface like below
public interface ApiInterface {
@Headers({
"Content-Type:application/x-www-form-urlencoded"
})
@POST("v1/users/check_status")
Call<CheckEmail> getEmailStatus(@Body String email);
}
Upvotes: 0
Reputation: 44813
Before accessing data in the response, you should check that the response itself is ok.
@Override
public void onResponse(Call<CheckEmail> call, Response<CheckEmail> response) {
if(response.isSuccessfull()){
//if you are sure that when the response is OK the list is not null
//you can leave this line below to hide the lint warning, otherwise
//before accessing the list with getData() check that response.body() is not null
//noinspection ConstantConditions
List<CheckEmailData> emailDataList = response.body().getData();
Log.d("Numer of Data : ", String.valueOf(emailDataList.size()));
for (CheckEmailData emailData : emailDataList){
Log.d("Successfull : ", String.valueOf(emailData.getStatus()));
}
} else {
//you got an error response, handle it
}
}
Upvotes: 0
Reputation: 319
In that JSON, "data" is an object, not an array. In your CheckEmail
class, change private List<CheckEmailData> data;
to private CheckEmailData data;
Upvotes: 1
Reputation: 321
You've got only one data, json object, from the api on the json response
{
"code": 1000,
"message": "OK",
"data": {
"id": "1",
"email": "[email protected]",
"status": "1",
"name": "test",
"category": "2"
}
}
yet you declare the data as a List
object, where it expect the data
above in a json array format.
you should change the List into
@SerializedName("data")
@Expose
private CheckEmailData data;
and I believe it would be fine.
Upvotes: 1