Mapping a JSONArray of dynamic JSONObject to java object in java - java

below written is my input json:
{
"apiData": [{
"apiName": "API",
"arguments": [{
"callFlow": "A"
}, {
"directoryName1": "CFAActivation"
}, {
"recDurationIVR1": "6000"
}, {
"numToDial": "*72"
}, {
"sleepDuration": "0000"
}],
"step": "1"
}]
}
//here "arguments" json array has dynamic json objects..

Respected Java Class According to your JSON
public class Arguments
{
private String callFlow;
public String getCallFlow ()
{
return callFlow;
}
public void setCallFlow (String callFlow)
{
this.callFlow = callFlow;
}
#Override
public String toString()
{
return "ClassPojo [callFlow = "+callFlow+"]";
}
}
public class ApiData
{
private Arguments[] arguments;
private String apiName;
private String step;
public Arguments[] getArguments ()
{
return arguments;
}
public void setArguments (Arguments[] arguments)
{
this.arguments = arguments;
}
public String getApiName ()
{
return apiName;
}
public void setApiName (String apiName)
{
this.apiName = apiName;
}
public String getStep ()
{
return step;
}
public void setStep (String step)
{
this.step = step;
}
#Override
public String toString()
{
return "ClassPojo [arguments = "+arguments+", apiName = "+apiName+", step = "+step+"]";
}
}
public class Jobj
{
private ApiData[] apiData;
public ApiData[] getApiData ()
{
return apiData;
}
public void setApiData (ApiData[] apiData)
{
this.apiData = apiData;
}
#Override
public String toString()
{
return "ClassPojo [apiData = "+apiData+"]";
}
}

Related

Convert json string response to pojo

I am calling an API using rest template like below:
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, entity, String.class);
And here is the json response string that i receive from the API
{
"data": {
"individuals": [
{
"cust_xref_id": "abf",
"cust_frd_alrt_in": "n",
"cust_satis_trd_ct": "4",
"gam_open_rv_trd_ct": "4",
"cust_extnl_delinq_90_day_ct": "1",
"cust_extnl_delinq_in": "y"
}
]
}
}
how can i map this response into a pojo? please help.
Required classes for the conversion are below,
1. DataDTO
public class DataDTO {
private IndividualList data;
public IndividualList getData() {
return data;
}
public void setData(IndividualList data) {
this.data = data;
}}
2. IndividualList
public class IndividualList {
private List<IndividualDTO> individuals;
public List<IndividualDTO> getIndividuals() {
return individuals;
}
public void setIndividuals(List<IndividualDTO> individuals) {
this.individuals = individuals;
}}
3. IndividualDTO
public class IndividualDTO {
#JsonProperty("cust_xref_id")
private String custXrefId;
#JsonProperty("cust_frd_alrt_in")
private String custFrdAlrtIn;
#JsonProperty("cust_satis_trd_ct")
private String custSatisTrdCt;
#JsonProperty("gam_open_rv_trd_ct")
private String gamOpenRvTrdCt;
#JsonProperty("cust_extnl_delinq_90_day_ct")
private String custExtnlDelinq90DayCt;
#JsonProperty("cust_extnl_delinq_in")
private String custExtnlDelinqIn;
public String getCustXrefId() {
return custXrefId;
}
public void setCustXrefId(String custXrefId) {
this.custXrefId = custXrefId;
}
public String getCustFrdAlrtIn() {
return custFrdAlrtIn;
}
public void setCustFrdAlrtIn(String custFrdAlrtIn) {
this.custFrdAlrtIn = custFrdAlrtIn;
}
public String getCustSatisTrdCt() {
return custSatisTrdCt;
}
public void setCustSatisTrdCt(String custSatisTrdCt) {
this.custSatisTrdCt = custSatisTrdCt;
}
public String getGamOpenRvTrdCt() {
return gamOpenRvTrdCt;
}
public void setGamOpenRvTrdCt(String gamOpenRvTrdCt) {
this.gamOpenRvTrdCt = gamOpenRvTrdCt;
}
public String getCustExtnlDelinq90DayCt() {
return custExtnlDelinq90DayCt;
}
public void setCustExtnlDelinq90DayCt(String custExtnlDelinq90DayCt) {
this.custExtnlDelinq90DayCt = custExtnlDelinq90DayCt;
}
public String getCustExtnlDelinqIn() {
return custExtnlDelinqIn;
}
public void setCustExtnlDelinqIn(String custExtnlDelinqIn) {
this.custExtnlDelinqIn = custExtnlDelinqIn;
}}
Tested Response:
{"data":{"individuals":[{"cust_xref_id":"abf","cust_frd_alrt_in":"n","cust_satis_trd_ct":"4","gam_open_rv_trd_ct":"4","cust_extnl_delinq_90_day_ct":"1","cust_extnl_delinq_in":"y"}]}}

Unable to deserialize HATEOS JSON using RestTemplate

I am trying to call a Spring Cloud Data Flow REST Endpoint which is supposed to return a list of all the executions of a task whose name is passed in the input.
For starters, I ran the following URL in the browser :
http://dataflow-server.myhost.net/tasks/executions?task1225
The following JSON is shown on the browser :
{
"_embedded": {
"taskExecutionResourceList": [
{
"executionId": 2908,
"exitCode": 0,
"taskName": "task1225",
"startTime": "2021-06-25T18:40:24.823+0000",
"endTime": "2021-06-25T18:40:27.585+0000",
"exitMessage": null,
"arguments": [
"--spring.datasource.username=******",
"--spring.cloud.task.name=task1225",
"--spring.datasource.url=******",
"--spring.datasource.driverClassName=org.h2.Driver",
"key=******",
"batchId=20210625_025755702",
"--spring.cloud.data.flow.platformname=default",
"--spring.cloud.task.executionid=2908"
],
"jobExecutionIds": [],
"errorMessage": null,
"externalExecutionId": "task1225-kp7mvwkmll",
"parentExecutionId": null,
"resourceUrl": "Docker Resource [docker:internal.artifactrepository.myhost.net/myProject/myimage:0.1]",
"appProperties": {
"spring.datasource.username": "******",
"spring.cloud.task.name": "task1225",
"spring.datasource.url": "******",
"spring.datasource.driverClassName": "org.h2.Driver"
},
"deploymentProperties": {
"spring.cloud.deployer.kubernetes.requests.memory": "512Mi",
"spring.cloud.deployer.kubernetes.limits.cpu": "1000m",
"spring.cloud.deployer.kubernetes.limits.memory": "8192Mi",
"spring.cloud.deployer.kubernetes.requests.cpu": "100m"
},
"taskExecutionStatus": "COMPLETE",
"_links": {
"self": {
"href": "http://dataflow-server.myhost.net/tasks/executions/2908"
}
}
}
]
},
"_links": {
"first": {
"href": "http://dataflow-server.myhost.net/tasks/executions?page=0&size=20"
},
"self": {
"href": "http://dataflow-server.myhost.net/tasks/executions?page=0&size=20"
},
"next": {
"href": "http://dataflow-server.myhost.net/tasks/executions?page=1&size=20"
},
"last": {
"href": "http://dataflow-server.myhost.net/tasks/executions?page=145&size=20"
}
},
"page": {
"size": 20,
"totalElements": 2908,
"totalPages": 146,
"number": 0
}
}
Next, I tried to call the same REST endpoint through Java; however, no matter what I try, the response object seems to be empty with none of the attributes populated :
Approach 1 : Custom domain classes created to deserialize the response. (Did not work. Empty content recieved in response)
ParameterizedTypeReference<Resources<TaskExecutions>> ptr = new ParameterizedTypeReference<Resources<TaskExecutions>>() {
};
ResponseEntity<Resources<TaskExecutions>> entity = restTemplate.exchange(
"http://dataflow-server.myhost.net/tasks/executions?task1225",
HttpMethod.GET, null, ptr);
System.out.println(entity.getBody().getContent()); **//empty content**
Where, TaskExecutions domain is as follows :
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "taskExecutionResourceList" })
#JsonIgnoreProperties(ignoreUnknown = true)
public class TaskExecutions {
public TaskExecutions() {
}
#JsonProperty("taskExecutionResourceList")
List<TaskExecutionResource> taskExecutionResourceList = new ArrayList<>();
#JsonProperty("taskExecutionResourceList")
public List<TaskExecutionResource> getTaskExecutionResourceList() {
return taskExecutionResourceList;
}
#JsonProperty("taskExecutionResourceList")
public void setTaskExecutionResourceList(List<TaskExecutionResource> taskExecutionResourceList) {
this.taskExecutionResourceList = taskExecutionResourceList;
}
}
And TaskExecutionResource is as follows :
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"executionId",
"exitCode",
"taskName",
"startTime",
"endTime",
"exitMessage",
"arguments",
"jobExecutionIds",
"errorMessage",
"externalExecutionId",
"parentExecutionId",
"resourceUrl",
"appProperties",
"deploymentProperties",
"taskExecutionStatus",
"_links" })
#JsonIgnoreProperties(ignoreUnknown = true)
public class TaskExecutionResource {
#JsonProperty("executionId")
private Integer executionId;
#JsonProperty("exitCode")
private Integer exitCode;
#JsonProperty("taskName")
private String taskName;
#JsonProperty("startTime")
private String startTime;
#JsonProperty("endTime")
private String endTime;
#JsonProperty("exitMessage")
private Object exitMessage;
#JsonProperty("arguments")
private List<String> arguments = new ArrayList<String>();
#JsonProperty("jobExecutionIds")
private List<Object> jobExecutionIds = new ArrayList<Object>();
#JsonProperty("errorMessage")
private Object errorMessage;
#JsonProperty("externalExecutionId")
private String externalExecutionId;
#JsonProperty("parentExecutionId")
private Object parentExecutionId;
#JsonProperty("resourceUrl")
private String resourceUrl;
#JsonProperty("appProperties")
private AppProperties appProperties;
#JsonProperty("deploymentProperties")
private DeploymentProperties deploymentProperties;
#JsonProperty("taskExecutionStatus")
private String taskExecutionStatus;
#JsonProperty("_links")
private Links links;
#JsonProperty("executionId")
public Integer getExecutionId() {
return executionId;
}
#JsonProperty("executionId")
public void setExecutionId(Integer executionId) {
this.executionId = executionId;
}
#JsonProperty("exitCode")
public Integer getExitCode() {
return exitCode;
}
#JsonProperty("exitCode")
public void setExitCode(Integer exitCode) {
this.exitCode = exitCode;
}
#JsonProperty("taskName")
public String getTaskName() {
return taskName;
}
#JsonProperty("taskName")
public void setTaskName(String taskName) {
this.taskName = taskName;
}
#JsonProperty("startTime")
public String getStartTime() {
return startTime;
}
#JsonProperty("startTime")
public void setStartTime(String startTime) {
this.startTime = startTime;
}
#JsonProperty("endTime")
public String getEndTime() {
return endTime;
}
#JsonProperty("endTime")
public void setEndTime(String endTime) {
this.endTime = endTime;
}
#JsonProperty("exitMessage")
public Object getExitMessage() {
return exitMessage;
}
#JsonProperty("exitMessage")
public void setExitMessage(Object exitMessage) {
this.exitMessage = exitMessage;
}
#JsonProperty("arguments")
public List<String> getArguments() {
return arguments;
}
#JsonProperty("arguments")
public void setArguments(List<String> arguments) {
this.arguments = arguments;
}
#JsonProperty("jobExecutionIds")
public List<Object> getJobExecutionIds() {
return jobExecutionIds;
}
#JsonProperty("jobExecutionIds")
public void setJobExecutionIds(List<Object> jobExecutionIds) {
this.jobExecutionIds = jobExecutionIds;
}
#JsonProperty("errorMessage")
public Object getErrorMessage() {
return errorMessage;
}
#JsonProperty("errorMessage")
public void setErrorMessage(Object errorMessage) {
this.errorMessage = errorMessage;
}
#JsonProperty("externalExecutionId")
public String getExternalExecutionId() {
return externalExecutionId;
}
#JsonProperty("externalExecutionId")
public void setExternalExecutionId(String externalExecutionId) {
this.externalExecutionId = externalExecutionId;
}
#JsonProperty("parentExecutionId")
public Object getParentExecutionId() {
return parentExecutionId;
}
#JsonProperty("parentExecutionId")
public void setParentExecutionId(Object parentExecutionId) {
this.parentExecutionId = parentExecutionId;
}
#JsonProperty("resourceUrl")
public String getResourceUrl() {
return resourceUrl;
}
#JsonProperty("resourceUrl")
public void setResourceUrl(String resourceUrl) {
this.resourceUrl = resourceUrl;
}
#JsonProperty("appProperties")
public AppProperties getAppProperties() {
return appProperties;
}
#JsonProperty("appProperties")
public void setAppProperties(AppProperties appProperties) {
this.appProperties = appProperties;
}
#JsonProperty("deploymentProperties")
public DeploymentProperties getDeploymentProperties() {
return deploymentProperties;
}
#JsonProperty("deploymentProperties")
public void setDeploymentProperties(DeploymentProperties deploymentProperties) {
this.deploymentProperties = deploymentProperties;
}
#JsonProperty("taskExecutionStatus")
public String getTaskExecutionStatus() {
return taskExecutionStatus;
}
#JsonProperty("taskExecutionStatus")
public void setTaskExecutionStatus(String taskExecutionStatus) {
this.taskExecutionStatus = taskExecutionStatus;
}
#JsonProperty("_links")
public Links getLinks() {
return links;
}
#JsonProperty("_links")
public void setLinks(Links links) {
this.links = links;
}
}
Approach 2 : Add spring-cloud-data-flow-rest as a maven dependency in my project and use the TaskExectuionResource entity defined in this project. :
TaskExecutionResource.Page = restTemplate.getForObject("http://dataflow-server.myhost.net/tasks/executions?task1225",
TaskExecutionResource.Page.class);//**Empty content**
Question : How can I deserialize the response of the JSON returned by a rest enndpoint that is using HATEOAS? It seems like a very daunting task to get this to work.
Not sure how you constructed RestTemplate but it doesn't work as is with hateoas and there's some additional steps you need to do.
To get idea what we've done see ObjectMapper config. There's hal module and additional mixin's what mapper needs to be aware of for these things to work.

I get null fields when I try to deserialize JSON with GSON

The Gist
I tried to deserialize some JSON text with GSON. The JSON string had values defined. However, the deserialized string has null values.
Exactly what I did
I tried to deserialize some JSON text with GSON
SomeSpec deserializedJson = GSON.fromJson(serializedJson, SomeSpec.class);
where serializedJson is a string containing
{
"some_class": "abc.def.SomeClass",
"stuff": [
"FOO",
"BAR",
],
"definition": {
"values": [
{ "feature": "FOO", "value": 1.0 },
{ "feature": "BAR", "value": 1.0 },
]
}
}
and SomeSpec is a java class containing:
package somepackagepath;
import java.util.List;
public class SomeSpec {
private List<FeatureValueSpec> _values;
private List<String> _postProcessFunctions;
public List<FeatureValueSpec> getValues() {
return _values;
}
public List<String> getPostProcessFunctions() {
return _postProcessFunctions;
}
public static class FeatureValueSpec {
private String _feature;
private float _value;
public String getFeature() {
return _feature;
}
public float getValue() {
return _value;
}
}
}
The deserialized object had only null fields even though the JSON clearly had those fields defined.
First: There are two errors in your JSON in Arrays. There are extra commas at end of each array.
Second your models should look like this
public class Values
{
private String value;
private String feature;
public String getValue ()
{
return value;
}
public void setValue (String value)
{
this.value = value;
}
public String getFeature ()
{
return feature;
}
public void setFeature (String feature)
{
this.feature = feature;
}
}
public class Definition
{
private Values[] values;
public Values[] getValues ()
{
return values;
}
public void setValues (Values[] values)
{
this.values = values;
}
}
public class MyPojo
{
private Definition definition;
private String[] stuff;
private String some_class;
public Definition getDefinition ()
{
return definition;
}
public void setDefinition (Definition definition)
{
this.definition = definition;
}
public String[] getStuff ()
{
return stuff;
}
public void setStuff (String[] stuff)
{
this.stuff = stuff;
}
public String getSome_class ()
{
return some_class;
}
public void setSome_class (String some_class)
{
this.some_class = some_class;
}
}

Rest Assured - Post nested POJO in Body

I'm trying to write an API class to send requests and handle responses from an API. Parts of the API have requests that require JSON bodies attached to the request such as this sample:
{
"Title": "string",
"Status": "string",
"ActFinish": "Date",
"ActHrs": "float",
"ActStart": "Date",
"ActualResults": "string",
"AssigneeUserId": "int",
"CustomFields": [
{
"Id": "string",
"Name": "string",
"Value": "string"
}
],
"Description": "string",
"EstFinish": "Date",
"EstHrs": "float",
"EstHrsRemaining": "float",
"EstStart": "Date",
"ExpectedResults": "string",
"FolderId": "int",
"FunctionalAreaCode": "string",
"HowFoundCode": "string",
"IssueCode": "string",
"ModuleCode": "string",
"PctComplete": "int",
"PriorityCode": "string",
"Resolution": "string",
"ResolutionCode": "string",
"SeverityCode": "string",
"SoftwareVersionCode": "string",
"StepsToRepro": "string"
}
The best way to do this I found through reading the Rest Assured documentation is with POJOs mentioned here: https://github.com/rest-assured/rest-assured/wiki/Usage#serialization
My POJO looks like this:
public class RequestDefectPost {
public String title;
public String status;
public Timestamp actFinish;
public float actHours;
public Timestamp actStart;
public String actualResults;
public int assigneeUserId;
public String[] customFields;
public String id;
public String name;
public String value;
public String description;
public Timestamp estFinish;
public float estHours;
public float estHrsRemaining;
public Timestamp estStart;
public String expectedResults;
public int folderId;
public String functionalAreaCode;
public String howFoundCode;
public String issueCode;
public String moduleCode;
public int pctComplete;
public String priorityCode;
public String resolutionCode;
public String severityCode;
public String softwareVersionCode;
public String stepsToRepro;
public RequestDefectPost(String title, String status) {
this.title = title;
this.status = status;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Timestamp getActFinish() {
return actFinish;
}
public void setActFinish(Timestamp actFinish) {
this.actFinish = actFinish;
}
public float getActHours() {
return actHours;
}
public void setActHours(float actHours) {
this.actHours = actHours;
}
public Timestamp getActStart() {
return actStart;
}
public void setActStart(Timestamp actStart) {
this.actStart = actStart;
}
public String getActualResults() {
return actualResults;
}
public void setActualResults(String actualResults) {
this.actualResults = actualResults;
}
public int getAssigneeUserId() {
return assigneeUserId;
}
public void setAssigneeUserId(int assigneeUserId) {
this.assigneeUserId = assigneeUserId;
}
public String[] getCustomFields() {
return customFields;
}
public void setCustomFields(String id, String name, String value) {
this.customFields = new String[]{this.id = id, this.name = name, this.value = value};
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Timestamp getEstFinish() {
return estFinish;
}
public void setEstFinish(Timestamp estFinish) {
this.estFinish = estFinish;
}
public float getEstHours() {
return estHours;
}
public void setEstHours(float estHours) {
this.estHours = estHours;
}
public float getEstHrsRemaining() {
return estHrsRemaining;
}
public void setEstHrsRemaining(float estHrsRemaining) {
this.estHrsRemaining = estHrsRemaining;
}
public Timestamp getEstStart() {
return estStart;
}
public void setEstStart(Timestamp estStart) {
this.estStart = estStart;
}
public String getExpectedResults() {
return expectedResults;
}
public void setExpectedResults(String expectedResults) {
this.expectedResults = expectedResults;
}
public int getFolderId() {
return folderId;
}
public void setFolderId(int folderId) {
this.folderId = folderId;
}
public String getFunctionalAreaCode() {
return functionalAreaCode;
}
public void setFunctionalAreaCode(String functionalAreaCode) {
this.functionalAreaCode = functionalAreaCode;
}
public String getHowFoundCode() {
return howFoundCode;
}
public void setHowFoundCode(String howFoundCode) {
this.howFoundCode = howFoundCode;
}
public String getIssueCode() {
return issueCode;
}
public void setIssueCode(String issueCode) {
this.issueCode = issueCode;
}
public String getModuleCode() {
return moduleCode;
}
public void setModuleCode(String moduleCode) {
this.moduleCode = moduleCode;
}
public int getPctComplete() {
return pctComplete;
}
public void setPctComplete(int pctComplete) {
this.pctComplete = pctComplete;
}
public String getPriorityCode() {
return priorityCode;
}
public void setPriorityCode(String priorityCode) {
this.priorityCode = priorityCode;
}
public String getResolutionCode() {
return resolutionCode;
}
public void setResolutionCode(String resolutionCode) {
this.resolutionCode = resolutionCode;
}
public String getSeverityCode() {
return severityCode;
}
public void setSeverityCode(String severityCode) {
this.severityCode = severityCode;
}
public String getSoftwareVersionCode() {
return softwareVersionCode;
}
public void setSoftwareVersionCode(String softwareVersionCode) {
this.softwareVersionCode = softwareVersionCode;
}
public String getStepsToRepro() {
return stepsToRepro;
}
public void setStepsToRepro(String stepsToRepro) {
this.stepsToRepro = stepsToRepro;
}
}
With my current POJO, the JSON being spit out by Rest Assured looks like this:
{
"title": "Test",
"status": "New",
"actFinish": null,
"actHours": 0.0,
"actStart": null,
"actualResults": null,
"assigneeUserId": 0,
"customFields": [
"Test",
"test",
"tesT"
],
"id": "Test",
"name": "test",
"value": "tesT",
"description": null,
"estFinish": null,
"estHours": 0.0,
"estHrsRemaining": 0.0,
"estStart": null,
"expectedResults": null,
"folderId": 0,
"functionalAreaCode": null,
"howFoundCode": null,
"issueCode": null,
"moduleCode": null,
"pctComplete": 0,
"priorityCode": null,
"resolutionCode": null,
"severityCode": null,
"softwareVersionCode": null,
"stepsToRepro": null
}
My question is how do I write the the customFields such that it is nested correctly, as outlined in the sample JSON?
You need another POJO that represents a "CustomFields". For example:
public class CustomFields {
private String Id;
private String Name;
private String Value;
<getters and setters>
}
and use List<CustomFields> CustomFields instead of String[] customFields. Also note that your JSON example doesn't use camel case for the property names so your POJO shouldn't use camel case either.
There are ways to avoid using a POJO at all in REST Assured. You can for example use a HashMap instead which could be easier in some situations.

JSON Exception - No value for in Android

I am getting this error message in my logcat 03-18 12:06:36.972: W/System.err(24574): org.json.JSONException: No value for title an I am stuck here. I am using Gson to parse JSON data. Here is my MainActivity and Model class.
I looked into other questions posted for same JSON Exception but I couldn't find the solution so I posted this question for my project
Also please advise if I am using correct method to display the data in the textview.
MainActivity
public class MainActivity extends AppCompatActivity {
public static final String Logcat = "vmech";
Button searchButton;
EditText editTextSearch;
TextView textViewDisplayResult;
String newText;
String urlstring;
public static final String MyAPIKey = "Your_Api_Key";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchButton = (Button) findViewById(R.id.buttonSerch);
editTextSearch = (EditText) findViewById(R.id.editTextSearch);
textViewDisplayResult = (TextView) findViewById(R.id.textViewDisplayResult);
searchButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
newText = editTextSearch.getText().toString();
if(newText.length()>0){
newText = newText.replace(" ", "+");
urlstring = "https://www.googleapis.com/books/v1/volumes?q=";
urlstring = urlstring + newText + "&maxResults=5" + "&key=" + MyAPIKey;
}
else {
Toast.makeText(MainActivity.this, "Please enter a book name to search.", Toast.LENGTH_LONG).show();
}
new JSONTask().execute(urlstring);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
Toast.makeText(this, "This is the Settings item", Toast.LENGTH_LONG).show();
return true;
}
public class JSONTask extends AsyncTask<String, String, List<BookInfoModel>>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected List<BookInfoModel> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader bufferedReader = null;
try {
URL url = new URL(urlstring);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream inputstream = connection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputstream));
StringBuffer stringbuffer = new StringBuffer();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
stringbuffer.append(line);
}
String finalJson = stringbuffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("items");
List<BookInfoModel> bookInfoModelList = new ArrayList<>();
String idText = null;
Gson gson = new Gson();
for(int i=0; i<parentArray.length(); i++){
JSONObject finalObject = parentArray.getJSONObject(i);
BookInfoModel bookInfoModel = gson.fromJson(finalObject.toString(),BookInfoModel.class);
bookInfoModelList.add(bookInfoModel);
}
return bookInfoModelList;
} catch (IOException e){
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null)
{
connection.disconnect();
}
try {
if (bufferedReader != null){
bufferedReader.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(List<BookInfoModel> result) {
super.onPostExecute(result);
textViewDisplayResult.setText((CharSequence) result);
}
}
}
Here is my model class for JSON data.
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class BookInfoModel {
private List<Items> items;
private String totalItems;
private String kind;
public List<Items> getItems() {
return items;
}
public void setItems(List<Items> items) {
this.items = items;
}
public String getTotalItems ()
{
return totalItems;
}
public void setTotalItems (String totalItems)
{
this.totalItems = totalItems;
}
public String getKind ()
{
return kind;
}
public void setKind (String kind)
{
this.kind = kind;
}
public class Items
{
private SaleInfo saleInfo;
private String id;
private SearchInfo searchInfo;
private String etag;
private List<VolumeInfo> volumeInfo;
private String selfLink;
private AccessInfo accessInfo;
private String kind;
public SaleInfo getSaleInfo ()
{
return saleInfo;
}
public void setSaleInfo (SaleInfo saleInfo)
{
this.saleInfo = saleInfo;
}
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
public SearchInfo getSearchInfo ()
{
return searchInfo;
}
public void setSearchInfo (SearchInfo searchInfo)
{
this.searchInfo = searchInfo;
}
public String getEtag ()
{
return etag;
}
public void setEtag (String etag)
{
this.etag = etag;
}
public List<VolumeInfo> getVolumeInfo() {
return volumeInfo;
}
public void setVolumeInfo(List<VolumeInfo> volumeInfo) {
this.volumeInfo = volumeInfo;
}
public String getSelfLink ()
{
return selfLink;
}
public void setSelfLink (String selfLink)
{
this.selfLink = selfLink;
}
public AccessInfo getAccessInfo ()
{
return accessInfo;
}
public void setAccessInfo (AccessInfo accessInfo)
{
this.accessInfo = accessInfo;
}
public String getKind ()
{
return kind;
}
public void setKind (String kind)
{
this.kind = kind;
}
public class SearchInfo
{
private String textSnippet;
public String getTextSnippet ()
{
return textSnippet;
}
public void setTextSnippet (String textSnippet)
{
this.textSnippet = textSnippet;
}
}
public class AccessInfo
{
private String webReaderLink;
private String textToSpeechPermission;
private String publicDomain;
private String viewability;
private String accessViewStatus;
private Pdf pdf;
private Epub epub;
private String embeddable;
private String quoteSharingAllowed;
private String country;
public String getWebReaderLink ()
{
return webReaderLink;
}
public void setWebReaderLink (String webReaderLink)
{
this.webReaderLink = webReaderLink;
}
public String getTextToSpeechPermission ()
{
return textToSpeechPermission;
}
public void setTextToSpeechPermission (String textToSpeechPermission)
{
this.textToSpeechPermission = textToSpeechPermission;
}
public String getPublicDomain ()
{
return publicDomain;
}
public void setPublicDomain (String publicDomain)
{
this.publicDomain = publicDomain;
}
public String getViewability ()
{
return viewability;
}
public void setViewability (String viewability)
{
this.viewability = viewability;
}
public String getAccessViewStatus ()
{
return accessViewStatus;
}
public void setAccessViewStatus (String accessViewStatus)
{
this.accessViewStatus = accessViewStatus;
}
public Pdf getPdf ()
{
return pdf;
}
public void setPdf (Pdf pdf)
{
this.pdf = pdf;
}
public Epub getEpub ()
{
return epub;
}
public void setEpub (Epub epub)
{
this.epub = epub;
}
public String getEmbeddable ()
{
return embeddable;
}
public void setEmbeddable (String embeddable)
{
this.embeddable = embeddable;
}
public String getQuoteSharingAllowed ()
{
return quoteSharingAllowed;
}
public void setQuoteSharingAllowed (String quoteSharingAllowed)
{
this.quoteSharingAllowed = quoteSharingAllowed;
}
public String getCountry ()
{
return country;
}
public void setCountry (String country)
{
this.country = country;
}
public class Pdf
{
private String acsTokenLink;
private String isAvailable;
public String getAcsTokenLink ()
{
return acsTokenLink;
}
public void setAcsTokenLink (String acsTokenLink)
{
this.acsTokenLink = acsTokenLink;
}
public String getIsAvailable ()
{
return isAvailable;
}
public void setIsAvailable (String isAvailable)
{
this.isAvailable = isAvailable;
}
}
public class Epub
{
private String acsTokenLink;
private String isAvailable;
public String getAcsTokenLink ()
{
return acsTokenLink;
}
public void setAcsTokenLink (String acsTokenLink)
{
this.acsTokenLink = acsTokenLink;
}
public String getIsAvailable ()
{
return isAvailable;
}
public void setIsAvailable (String isAvailable)
{
this.isAvailable = isAvailable;
}
}
}
public class SaleInfo
{
private RetailPrice retailPrice;
private String saleability;
private ListPrice listPrice;
private Offers[] offers;
private String buyLink;
private String isEbook;
private String country;
public RetailPrice getRetailPrice ()
{
return retailPrice;
}
public void setRetailPrice (RetailPrice retailPrice)
{
this.retailPrice = retailPrice;
}
public String getSaleability ()
{
return saleability;
}
public void setSaleability (String saleability)
{
this.saleability = saleability;
}
public ListPrice getListPrice ()
{
return listPrice;
}
public void setListPrice (ListPrice listPrice)
{
this.listPrice = listPrice;
}
public Offers[] getOffers ()
{
return offers;
}
public void setOffers (Offers[] offers)
{
this.offers = offers;
}
public String getBuyLink ()
{
return buyLink;
}
public void setBuyLink (String buyLink)
{
this.buyLink = buyLink;
}
public String getIsEbook ()
{
return isEbook;
}
public void setIsEbook (String isEbook)
{
this.isEbook = isEbook;
}
public String getCountry ()
{
return country;
}
public void setCountry (String country)
{
this.country = country;
}
public class Offers
{
private RetailPrice retailPrice;
private ListPrice listPrice;
private String finskyOfferType;
public RetailPrice getRetailPrice ()
{
return retailPrice;
}
public void setRetailPrice (RetailPrice retailPrice)
{
this.retailPrice = retailPrice;
}
public ListPrice getListPrice ()
{
return listPrice;
}
public void setListPrice (ListPrice listPrice)
{
this.listPrice = listPrice;
}
public String getFinskyOfferType ()
{
return finskyOfferType;
}
public void setFinskyOfferType (String finskyOfferType)
{
this.finskyOfferType = finskyOfferType;
}
}
public class RetailPrice
{
private String amount;
private String currencyCode;
public String getAmount ()
{
return amount;
}
public void setAmount (String amount)
{
this.amount = amount;
}
public String getCurrencyCode ()
{
return currencyCode;
}
public void setCurrencyCode (String currencyCode)
{
this.currencyCode = currencyCode;
}
}
public class ListPrice
{
private String amount;
private String currencyCode;
public String getAmount ()
{
return amount;
}
public void setAmount (String amount)
{
this.amount = amount;
}
public String getCurrencyCode ()
{
return currencyCode;
}
public void setCurrencyCode (String currencyCode)
{
this.currencyCode = currencyCode;
}
}
}
public class VolumeInfo
{
private String pageCount;
private String averageRating;
private ReadingModes readingModes;
private String infoLink;
private String printType;
private String allowAnonLogging;
private String publisher;
private String[] authors;
private String canonicalVolumeLink;
#SerializedName("title")
private String title;
private String previewLink;
private String description;
private String ratingsCount;
private ImageLinks imageLinks;
private String contentVersion;
private String[] categories;
private String language;
private String publishedDate;
private IndustryIdentifiers[] industryIdentifiers;
private String maturityRating;
public String getPageCount ()
{
return pageCount;
}
public void setPageCount (String pageCount)
{
this.pageCount = pageCount;
}
public String getAverageRating ()
{
return averageRating;
}
public void setAverageRating (String averageRating)
{
this.averageRating = averageRating;
}
public ReadingModes getReadingModes ()
{
return readingModes;
}
public void setReadingModes (ReadingModes readingModes)
{
this.readingModes = readingModes;
}
public String getInfoLink ()
{
return infoLink;
}
public void setInfoLink (String infoLink)
{
this.infoLink = infoLink;
}
public String getPrintType ()
{
return printType;
}
public void setPrintType (String printType)
{
this.printType = printType;
}
public String getAllowAnonLogging ()
{
return allowAnonLogging;
}
public void setAllowAnonLogging (String allowAnonLogging)
{
this.allowAnonLogging = allowAnonLogging;
}
public String getPublisher ()
{
return publisher;
}
public void setPublisher (String publisher)
{
this.publisher = publisher;
}
public String[] getAuthors ()
{
return authors;
}
public void setAuthors (String[] authors)
{
this.authors = authors;
}
public String getCanonicalVolumeLink ()
{
return canonicalVolumeLink;
}
public void setCanonicalVolumeLink (String canonicalVolumeLink)
{
this.canonicalVolumeLink = canonicalVolumeLink;
}
public String getTitle ()
{
return title;
}
public void setTitle (String title)
{
this.title = title;
}
public String getPreviewLink ()
{
return previewLink;
}
public void setPreviewLink (String previewLink)
{
this.previewLink = previewLink;
}
public String getDescription ()
{
return description;
}
public void setDescription (String description)
{
this.description = description;
}
public String getRatingsCount ()
{
return ratingsCount;
}
public void setRatingsCount (String ratingsCount)
{
this.ratingsCount = ratingsCount;
}
public ImageLinks getImageLinks ()
{
return imageLinks;
}
public void setImageLinks (ImageLinks imageLinks)
{
this.imageLinks = imageLinks;
}
public String getContentVersion ()
{
return contentVersion;
}
public void setContentVersion (String contentVersion)
{
this.contentVersion = contentVersion;
}
public String[] getCategories ()
{
return categories;
}
public void setCategories (String[] categories)
{
this.categories = categories;
}
public String getLanguage ()
{
return language;
}
public void setLanguage (String language)
{
this.language = language;
}
public String getPublishedDate ()
{
return publishedDate;
}
public void setPublishedDate (String publishedDate)
{
this.publishedDate = publishedDate;
}
public IndustryIdentifiers[] getIndustryIdentifiers ()
{
return industryIdentifiers;
}
public void setIndustryIdentifiers (IndustryIdentifiers[] industryIdentifiers)
{
this.industryIdentifiers = industryIdentifiers;
}
public String getMaturityRating ()
{
return maturityRating;
}
public void setMaturityRating (String maturityRating)
{
this.maturityRating = maturityRating;
}
public class ImageLinks
{
private String thumbnail;
private String smallThumbnail;
public String getThumbnail ()
{
return thumbnail;
}
public void setThumbnail (String thumbnail)
{
this.thumbnail = thumbnail;
}
public String getSmallThumbnail ()
{
return smallThumbnail;
}
public void setSmallThumbnail (String smallThumbnail)
{
this.smallThumbnail = smallThumbnail;
}
}
public class ReadingModes
{
private String text;
private String image;
public String getText ()
{
return text;
}
public void setText (String text)
{
this.text = text;
}
public String getImage ()
{
return image;
}
public void setImage (String image)
{
this.image = image;
}
}
public class IndustryIdentifiers
{
private String type;
private String identifier;
public String getType ()
{
return type;
}
public void setType (String type)
{
this.type = type;
}
public String getIdentifier ()
{
return identifier;
}
public void setIdentifier (String identifier)
{
this.identifier = identifier;
}
}
}
}
}
Here is the JSON data I m trying to Parse.
{
"kind": "books#volumes",
"totalItems": 1557,
"items": [
{
"kind": "books#volume",
"id": "An4_e3Cr3zAC",
"etag": "DWmqBRkB8dw",
"selfLink": "https://www.googleapis.com/books/v1/volumes/An4_e3Cr3zAC",
"volumeInfo": {
"title": "The Rules of the Game",
"authors": [
"Neil Strauss"
],
"publisher": "Canongate Books",
"publishedDate": "2011-09-29",
"description": "If you want to play The Game you need to know The Rules This book is not a story.",
"industryIdentifiers": [
{
"type": "ISBN_13",
"identifier": "9781847673558"
},
{
"type": "ISBN_10",
"identifier": "1847673554"
}
],
"readingModes": {
"text": true,
"image": true
},
"pageCount": 352,
"printType": "BOOK",
"categories": [
"Biography & Autobiography"
],
"averageRating": 3.5,
"ratingsCount": 82,
"maturityRating": "NOT_MATURE",
"allowAnonLogging": true,
"contentVersion": "1.7.6.0.preview.3",
"imageLinks": {
"smallThumbnail": "http://books.google.co.in/books/content?id=An4_e3Cr3zAC&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
"thumbnail": "http://books.google.co.in/books/content?id=An4_e3Cr3zAC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
},
"language": "en",
"previewLink": "http://books.google.co.in/books?id=An4_e3Cr3zAC&printsec=frontcover&dq=game&hl=&cd=1&source=gbs_api",
"infoLink": "http://books.google.co.in/books?id=An4_e3Cr3zAC&dq=game&hl=&source=gbs_api",
"canonicalVolumeLink": "http://books.google.co.in/books/about/The_Rules_of_the_Game.html?hl=&id=An4_e3Cr3zAC"
},
"saleInfo": {
"country": "IN",
"saleability": "FOR_SALE",
"isEbook": true,
"listPrice": {
"amount": 399.0,
"currencyCode": "INR"
},
"retailPrice": {
"amount": 279.3,
"currencyCode": "INR"
},
"buyLink": "http://books.google.co.in/books?id=An4_e3Cr3zAC&dq=game&hl=&buy=&source=gbs_api",
"offers": [
{
"finskyOfferType": 1,
"listPrice": {
"amountInMicros": 3.99E8,
"currencyCode": "INR"
},
"retailPrice": {
"amountInMicros": 2.793E8,
"currencyCode": "INR"
}
}
]
},
"accessInfo": {
"country": "IN",
"viewability": "PARTIAL",
"embeddable": true,
"publicDomain": false,
"textToSpeechPermission": "ALLOWED",
"epub": {
"isAvailable": true,
"acsTokenLink": "http://books.goo"
},
"pdf": {
"isAvailable": true,
"acsTokenLink": "http://books.google.co.in/books/download/The_Rules_of_the_Game-sample-pdf.acsm?id=An4_e3Cr3zAC&format=pdf&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
},
"webReaderLink": "http://books.google.co.in/books/reader?id=An4_e3Cr3zAC&hl=&printsec=frontcover&output=reader&source=gbs_api",
"accessViewStatus": "SAMPLE",
"quoteSharingAllowed": false
},
"searchInfo": {
"textSnippet": "He's tested the specific material."
}
}
]
}
Here is the stacktrace form logcat. https://codeshare.io/Ag78v
Replace your Items class with below:
public class Items
{
private SaleInfo saleInfo;
private String id;
private SearchInfo searchInfo;
private String etag;
private VolumeInfo volumeInfo;
private String selfLink;
private AccessInfo accessInfo;
private String kind;
public SaleInfo getSaleInfo ()
{
return saleInfo;
}
public void setSaleInfo (SaleInfo saleInfo)
{
this.saleInfo = saleInfo;
}
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
public SearchInfo getSearchInfo ()
{
return searchInfo;
}
public void setSearchInfo (SearchInfo searchInfo)
{
this.searchInfo = searchInfo;
}
public String getEtag ()
{
return etag;
}
public void setEtag (String etag)
{
this.etag = etag;
}
public VolumeInfo getVolumeInfo() {
return volumeInfo;
}
public void setVolumeInfo(VolumeInfo volumeInfo) {
this.volumeInfo = volumeInfo;
}
public String getSelfLink ()
{
return selfLink;
}
public void setSelfLink (String selfLink)
{
this.selfLink = selfLink;
}
public AccessInfo getAccessInfo ()
{
return accessInfo;
}
public void setAccessInfo (AccessInfo accessInfo)
{
this.accessInfo = accessInfo;
}
public String getKind ()
{
return kind;
}
public void setKind (String kind)
{
this.kind = kind;
}
}
You are not using the serializedName annotation. Use it as follows in your model.
public class Items
{
#SerializedName("Your-key-from JSON Response")
private SaleInfo saleInfo;
#SerializedName("Your-key-from JSON Response")
private String id;
#SerializedName("Your-key-from JSON Response")
private SearchInfo searchInfo;
#SerializedName("Your-key-from JSON Response")
private String etag;
#SerializedName("Your-key-from JSON Response")
private VolumeInfo volumeInfo;
#SerializedName("Your-key-from JSON Response")
private String selfLink;
#SerializedName("Your-key-from JSON Response")
private AccessInfo accessInfo;
#SerializedName("Your-key-from JSON Response")
private String kind;
public SaleInfo getSaleInfo ()
{
return saleInfo;
}
public void setSaleInfo (SaleInfo saleInfo)
{
this.saleInfo = saleInfo;
}
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
}
One of Your ListItem VolumeInfo have null value for title. By default Gson wont parse null value. But you can make to ignore null values when parsing. by doing the following.
Gson gson = new GsonBuilder().serializeNulls().create();
Try this.

Categories