I want to parse json from json object and put it on textview. I tried some method but failed. The error:
expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
API SERVICE: Full ver http://139.255.86.189:83/service/api/checklistpertanyaan/1
{
"success": true,
"data": [
{
"idRchecklistpompa": "1",
"nmChecklist": "Membersihkan Body Pompa"
},
{
"idRchecklistpompa": "2",
"nmChecklist": "Membersihkan Kabel Tray Pompa"
},
Harian.java
public class Harian {
#SerializedName("idRchecklistpompa")
#Expose
private String idRchecklistpompa;
#SerializedName("nmChecklist")
#Expose
private String nmChecklist;
public String getIdRchecklistpompa() {
return idRchecklistpompa;
}
public String getNmChecklist() {
return nmChecklist;
}
public void setIdRchecklistpompa(String idRchecklistpompa) {
this.idRchecklistpompa = idRchecklistpompa;
}
public void setNmChecklist(String nmChecklist) {
this.nmChecklist = nmChecklist;
}
}
MainActivity.java
public class HarianActivity extends AppCompatActivity {
private TextView textViewResult;
/*private static String url = "http://139.255.86.189:83/service/api/checklistpertanyaan/1";*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_harian);
textViewResult = findViewById(R.id.text_view_result);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://139.255.86.189:83/service/api/")
.addConverterFactory(GsonConverterFactory.create())
.build();
HarianApi harianApi = retrofit.create(HarianApi.class);
Call<List<Harian>> call = harianApi.getHarian();
call.enqueue(new Callback<List<Harian>>() {
#Override
public void onResponse(Call<List<Harian>> call, Response<List<Harian>> response) {
if (!response.isSuccessful()) {
textViewResult.setText("CodeL " + response.code());
return;
}
List<Harian> harians = response.body();
for (Harian harian : harians) {
String content = "";
content += "ID " + harian.getIdRchecklistpompa() + "\n";
content += "NAMA " + harian.getNmChecklist() + "\n";
textViewResult.append(content);
}
}
#Override
public void onFailure(Call<List<Harian>> call, Throwable t) {
textViewResult.setText(t.getMessage());
}
});
}
}
I would expect JSON that encapsulated a List of Harians to look like this:
[
{
"idRchecklistpompa": "1",
"nmChecklist": "Membersihkan Body Pompa"
},
{
"idRchecklistpompa": "2",
"nmChecklist": "Membersihkan Kabel Tray Pompa"
}
]
Instead, yours begins with:
{
"success": true,
"data": [
...
So it isn't correct for your API to return List<Harian>. Instead, your API should return a different class which looks more like:
public class Container {
#SerializedName("success")
private boolean success;
#SerializedName("data")
List<Harian> data;
public static class Harian {
#SerializedName("idRchecklistpompa")
#Expose
private String idRchecklistpompa;
#SerializedName("nmChecklist")
#Expose
private String nmChecklist;
public String getIdRchecklistpompa() {
return idRchecklistpompa;
}
public String getNmChecklist() {
return nmChecklist;
}
public void setIdRchecklistpompa(String idRchecklistpompa) {
this.idRchecklistpompa = idRchecklistpompa;
}
public void setNmChecklist(String nmChecklist) {
this.nmChecklist = nmChecklist;
}
}
}
And have your Retrofit API return Container rather than List<Harian>
Not sure if I understand but, to debug the problem what I would do is:
1.- Check as a String that response is a well formed JSON String.
Log.d(TAG, "My JSON String: " + response.code());
1.5.- Check if that string is a JSONObject or a JSONArray
2.- Probably try to create a JSONObject/JSONArray from that String to see if it triggers an exception.
try {
JSONObject jsonObject = new JSONObject(response.code());
} catch (JSONException e) {
e.printStackTrace();
}
3.- Try to parse the JSONObject but checking for exceptions:
try {
String nmChecklist = jsonObject.getString("nmChecklist");
} catch (JSONException e) {
e.printStackTrace();
}
4.- If you want to avoid exceptions since some objects may or may not have a key or value:
String nmChecklist = jsonObject.has("nmChecklist") && !jsonObject.isNull("nmChecklist") ? jsonObject.getString("nmChecklist") : null;
I hope this helps.
I think there is some problem with your class. The response is different from your pojo class. See json to pojo and create your Model as per the generated pojo.
Related
I made a post request method with Retrofit2 but I encountered this problem on my response.
Expected a string but was BEGIN_OBJECT at line 3 column 4 path $.SUCCESS
The response should be
{
"SUCCESS" :
{
"200" : "access granted",
"ra" : "approved",
"la" : "approved",
"ch" : "approved"
}
}
I uses this code for the post request
#POST("login")
Call<Post> createPost(#Body Post post);
And for the POJO class
public class Post {
private String anthony;
private String SUCCESS;
public Post(String name) {
this.anthony = name;
}
public String getSUCCESS() {
return SUCCESS;
}
}
For the method I use the following code
private void createPost() {
Post post = new Post("mypassword");
Call<Post> call = jsonPlaceHolderApi.createPost(post);
call.enqueue(new Callback<Post>() {
#Override
public void onResponse(Call<Post> call, Response<Post> response) {
if (!response.isSuccessful()) {
textViewResult.setText("Code: " + response.code());
return;
}
Post postResponse = response.body();
String content = "";
content += "Code: " + response.code() + "\n";
content += "S" + postResponse.getSUCCESS();
textViewResult.setText(content);
}
#Override
public void onFailure(Call<Post> call, Throwable t) {
textViewResult.setText(t.getMessage());
}
});
}
Does anyone know what's wrong with my code? I expected to get the response inside the "SUCCESS" json object.
You expect SUCCESS to be an object in your wanted response but you have defined it as a String in your Post class. You should use an object for SUCCESS instead.
public class Post {
private String anthony;
private PostSuccess SUCCESS;
public Post(String name) {
this.anthony = name;
}
public PostSuccess getSUCCESS() {
return SUCCESS;
}
}
public class PostSuccess {
#JsonProperty("200")
private String _200;
private String ra;
private String la;
private String ch;
}
I looked at some other threads about this topic and integrated the solution it offered but it still throws the same error. this is the first time i try to call an api on android. here i want to 'GET' an array of objects. There is no stack trace since the app does not crash. i think the problem has to do with the array of questions.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.1.100:3000/api/")
.addConverterFactory(GsonConverterFactory.create())
.build();
JsonPlaceHolderApi jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi.class);
Call<List<Post>> call = jsonPlaceHolderApi.getPosts();
call.enqueue(new Callback<List<Post>>() {
#Override
public void onResponse(Call<List<Post>> call, Response<List<Post>> response) {
if (!response.isSuccessful()){
textViewResult.setText("Code: " + response.code());
return;
}
List<Post> posts = response.body();
for (Post post : posts){
String content = "";
content += "Doctor: " + post.getDoctor() + "\n";
content += "Name: " + post.getName() + "\n";
content += "Questions: " + post.getQuestions() + "\n\n";
textViewResult.append(content);
}
}
#Override
public void onFailure(Call<List<Post>> call, Throwable t) {
textViewResult.setText(t.getMessage());
}
});
here is an example of the json data:
[
{
"questions":[...],
"_id":"5f42954a7e252b48ec3564b6",
"name":"Lifestyle",
"doctor":"doctoremail#gmail.com",
"__v":0
},
{
"questions":[...],
"_id":"5f4299687e252b48ec3564b7",
"name":"Headache",
"doctor":"doctoremail#gmail.com",
"__v":0
},
{
"questions":[...],
"_id":"5f429b2f7e252b48ec3564b9",
"name":"Foot pain",
"doctor":"doctoremail#gmail.com",
"__v":0
}
]
I fixed it. the problem was that the 'questions' property in my model was of type string in stead of List String
package com.example.medlog;
import java.util.List;
public class Post {
private String name;
private String doctor;
private List<String> questions;
public String getName() {
return name;
}
public String getDoctor() {
return doctor;
}
public List<String> getQuestions() {
return questions;
}
}
{ "StatusCode": 200, "StatusDescription": "OK", "ErrorMessage":
"", "ErrorDetail": "", "Results": [
{
"Key": "AccessTokens",
"Value": "[{\"Key\":\"XXXXX",
\"Value\":\"BABABA\"},{\"Key\":\"DIDADIDA\",\"Value\":\"YYYYY"
} ]"}]}
This is the response i will get when i success call the API. The datatype of "Results" is List. Can anyone explain for me how to get the "Key" and the "Value".
My Object Classes
public class KeyValueItem {
private String Key;
private String Value;
public String getKey() {
return Key;
}
public void setKey(String key) {
Key = key;
}
public String getValue() {
return Value;
}
public void setValue(String value) {
Value = value;
}
}
Response Class
public class RestServiceResponse {
#SerializedName("StatusCode")
#Expose
public int StatusCode;
public int getStatusCode() {
return StatusCode;
}
#SerializedName("StatusDescription")
#Expose
public String StatusDescription;
public String getStatusDescription() {
return StatusDescription;
}
#SerializedName("ErrorMessage")
#Expose
public String ErrorMessage;
public String getErrorMessage() {
return ErrorMessage;
}
#SerializedName("ErrorDetail")
#Expose
public String ErrorDetail;
public String getErrorDetail() {
return ErrorDetail;
}
#SerializedName("Results")
#Expose
public List<KeyValueItem> Results;
public List<KeyValueItem> getResults() {
return Results;
}
}
Anyone help please =(
Some of my code:
public void onResponse(Call<RestServiceResponse> call, Response<RestServiceResponse> response) {
Log.i("ddsddsadsa", String.valueOf(response.code()));
RestServiceResponse restServiceResponse = response.body();
if(restServiceResponse.getStatusCode() == 200){
List<KeyValueItem> list = response.body().getResults();
JSONArray jsonArray = new JSONArray(list);
try {
JSONObject job = jsonArray.getJSONObject(1);
String testttt = job.getString("Key");
Log.i("dsadsadsadas", testttt);
} catch (JSONException e) {
e.printStackTrace();
}
}
2 things you have to understand first.
Your JSON data is not in valid format. It contains \ (slashes) to escape double quotes in key-value pair. To confirm whether the returned JSON data is valid or not please copy & paste your JSON response into JSON validator and Formatter. Maybe problem in server script.
If you're using GsonConvertorFactory with Retrofit, Retrofit will automatically converts JSON response data to POJO internally. So, you don't need parse it again inside onResponse() method. If you get proper JSON response from server side then use it like below.
public void onResponse(Call<RestServiceResponse> call, Response<RestServiceResponse> response) {
// code....
RestServiceResponse restServiceResponse = response.body();
if (restServiceResponse.getStatusCode() == 200) {
List<KeyValueItem> list = response.body().getResults();
for(int i = 0; i < list.size(); i++) {
KeyValueItem kvi = list.get(i);
// do whatever you want with kvi object
}
}
}
public void onResponse(Call<RestServiceResponse> call, Response<RestServiceResponse> response) {
Log.i("ddsddsadsa", String.valueOf(response.code()));
RestServiceResponse restServiceResponse = response.body();
if(restServiceResponse.getStatusCode() == 200){
List<KeyValueItem> list = response.body().getResults();
for(KeyValueItem keyValueItem : list) {
String key = keyValueItem.getKey();
String value = keyValueItem.getValue();
Log.i("Keykeykey", key);
}
try {
JSONArray jsonArray = new JSONArray(value);
for(int i = 0; i < jsonArray.length();i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String keykey = obj.getString("Key");
String VAlll = obj.getString("Value");
Log.i("c1111",keykey);
Log.i("c222222", VAlll);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}else if(restServiceResponse.getErrorMessage() != null){
builder = new AlertDialog.Builder(LoginActivity.this);
builder.setTitle("Error");
builder.setMessage(restServiceResponse.getErrorMessage());
builder.setPositiveButton("Ok",null);
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
}
OK. Btw. i have try this to get my result. and it works!
To answer those about a invalid JSON format maybe because i have changed the value of the JSON so may have some mistake on it.
Below is the final log i get:
74/com.appandus.user.konnect I/Keykeykey: AccessTokens 07-12
17:14:38.177 6274-6274/com.appandus.user.konnect I/c1111: XXXXX 07-12
17:14:38.177 6274-6274/com.appandus.user.konnect I/c222222: BABABA
07-12 17:14:38.177 6274-6274/com.appandus.user.konnect I/c1111: NS/NH
: DIDAIDA 07-12 17:14:38.177 6274-6274/com.appandus.user.konnect
I/c222222: YYYYYY
So I was following this tutorial and it has this method.
new AsyncTask<Void,Void,Void>(){
#Override
protected Void doInBackground(Void... voids) {
Reader reader=API.getData("http://beta.json-generator.com/api/json/get/DiIRBM4");
Type listType = new TypeToken<ArrayList<DoctorBean>>(){}.getType();
beanPostArrayList = new GsonBuilder().create().fromJson(reader, listType);
postList=new StringBuffer();
for(DoctorBean post: beanPostArrayList){
postList.append("\n heroName: "+post.getHeroName()+"\n realName: "+post.getRealName()+"\n\n");
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Log.d("JSON Result ", postList.toString());
}
}.execute();
The Log Result would only show these values.
JSON Result:
heroName: null realName: null
heroName: null realName: null
heroName: null realName: null
This is my JSON data
[
{
"heroName": "Dr. Strange",
"realName": "Stephen Strange"
},
{
"heroName": "Spider-Man",
"realName": "Peter Paker"
},
{
"heroName": "Captain America",
"realName": "Stever Rogers"
}
]
This is my Data Model
import com.google.gson.annotations.SerializedName;
public class DoctorBean {
#SerializedName("heroName")
private String heroName;
#SerializedName("realName")
private String realName;
public DoctorBean(String heroName, String realName) {
this.heroName = heroName;
this.realName = realName;
}
public String getHeroName() {
return heroName;
}
public void setHeroName(String heroName) {
this.heroName = heroName;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
}
And this is my API class
public class API {
private static Reader reader=null;
public static Reader getData(String SERVER_URL) {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(SERVER_URL);
HttpResponse response = httpClient.execute(httpPost);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
reader = new InputStreamReader(content);
} else {
// Log.e("error:", "Server responded with status code: "+ statusLine.getStatusCode());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return reader;
}
}
I noticed that the log Result showed 3 rows, so I was thinking it was able to get the length of the array correctly. But as for the data, all was null.
As per your given tutorial,from this link response is as below:
[
{
"date":"11/8/2014",
"auther":"nirav kalola",
"description":"json object parsing using gson library is easy",
"post_name":"json object parsing"
},
{
"date":"12/8/2014",
"auther":"nirav kalola",
"description":"json array parsing using gson library",
"post_name":"json array parsing"
},
{
"date":"17/8/2014",
"auther":"nirav kalola",
"description":"store json file in assets folder and get data when required",
"post_name":"json parsing from assets folder"
}
]
So you need to try below POJO class for GSONBuilder. Replace your name with BeanPost.
import com.google.gson.annotations.SerializedName;
public class BeanPost {
#SerializedName("post_name")
private String post_name;
#SerializedName("auther")
private String auther;
#SerializedName("date")
private String date;
#SerializedName("description")
private String description;
public BeanPost(String post_name, String auther, String date, String description) {
this.post_name = post_name;
this.auther = auther;
this.date = date;
this.description = description;
}
public String getPost_name() {
return post_name;
}
public void setPost_name(String post_name) {
this.post_name = post_name;
}
public String getAuther() {
return auther;
}
public void setAuther(String auther) {
this.auther = auther;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Try to create beanPostArrayList as above pojo class arraylist. And try your code and get appropriate fields from it.
I hope its helps you.
Try this.
Create an array from response :
DoctorBean[] doctorBeanArray = new Gson().fromJson(response, DoctorBean[].class); // Where response is your string response
Then create an ArrayList :
ArrayList<DoctorBean> doctorBeanList = new ArrayList<DoctorBean>(Arrays.asList(doctorBeanArray));
I am building an android application and I am new to json. I am fetching below josn formate -
{
"contact"[
{
"key1": "hey1",
"key2": [
{
"key3": "hey2"
}
]
}
]
}
I am using below code to fetch key1 value. Now problem I am facing is how to fetch key3 value -
jsonString = http.makeServiceCall(url, ServiceHandler.GET, null);
if (jsonString != null) {
try {
JSONObject jsonObj = new JSONObject(jsonString);
// Getting JSON Array node
questions = jsonObj.getJSONArray(TAG_CONTACTS);
for (int i = 0; i < questions.length(); i++) {
temp_obj = questions.getJSONObject(i);
key1Array.add(temp_obj.getString("key1").toString());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Please help me
If you want to use Gson to parse your json data. Let try it:
First of all, you must modify your json like this:
{
"contact":[
{
"key1": "hey1",
"key2": [
{
"key3": "hey2"
}
]
}
]
}
Second add Gson to your libs and sync build.gradle: download here extract it, and copy/past gson-2.2.4.gson to libs folder.
Third Create some class:
FullContents.java:
public class FullContents {
private List<ObjectKey> contact;
public List<ObjectKey> getContact() {
return contact;
}
public void setContact(List<ObjectKey> contact) {
this.contact = contact;
}
}
ObjectKey.java:
public class ObjectKey {
private String key1;
private List<ObjectKey3> key2;
public List<ObjectKey3> getKey2() {
return key2;
}
public void setKey2(List<ObjectKey3> key2) {
this.key2 = key2;
}
public String getKey1(){
return key1;
}
public void setKey1(String key1){
this.key1 = key1;
}
}
ObjectKey3.java:
public class ObjectKey3 {
private String key3;
public String getKey3(){
return key3;
}
public void setKey3(String key3){
this.key3 = key3;
}
}
And Finally, get data from url:
private class ParseByGson extends AsyncTask<String,Void,FullContents> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected FullContents doInBackground(String... params) {
FullContents fullContents = null;
try {
URL url=new URL(params[0]);
InputStreamReader reader=new InputStreamReader(url.openStream(),"UTF-8");
fullContents=new Gson().fromJson(reader,FullContents.class);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fullContents;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(FullContents results) {
super.onPostExecute(results);
ObjectKey objectKey = results.getContact().get(0);
Log.e(">>",objectKey.getKey1()+"--");
}
}
you can put below code to onCreate:
ParseByGson parseByGson = new ParseByGson();
parseByGson.execute(urlStringHere);
Update: Explain
1st of all: your json appears to be not valid (missing ':' after "content");
After reviewing thins:
You can use the named getters to retrieve many types of results (object, int, string, etc);
JSONObject contact = jsonObj.getJSONObject("contact"); // {"key1":"hey1","key2":[{"key3":"hey2"}]}
or
String key1 = jsonObj.getString("key1"); // hey1
To retrieve key3, you should use:
JSONObject contact = jsonObj.getJSONObject("contact");
JSONObject key2 = contact.getJSONObject("key2");
String key3 = key2.getString("key3");
Adapt the following code to what you are coding
for (int i = 0; i < questions.length(); i++) {
temp_obj = questions.getJSONObject(i);
key1Array.add(temp_obj.getString("key1"));
JSONObject temp_objKey2 = temp_obj.getJSONObject("key2");
Key2Object key2Object = new Key2Object();
key2Object.add(temp_objKey2.getString("key3"));
key1Array.add(key2Object);
}