How can I set label names manually on a loop springboot? - java

I have a JSON array below, I want to be able to set label names that make sense instead of the entity names. Am generating tables dynamically using this data, I want the rows to have names that make more sense to the end user by assigning custom Label names. the recordtype generates new tab names
This is my JSON
[
{
"country": "USA",
"projectId": "USAID2020,
"case": "2014",
"recordType": "Identification",
"itemDetails": [
{
"ItemValue": "023",
"Label": "hA",
"ItemValueLabel": "023",
"Name": "hA"
},
{
"ItemValue": "0005",
"Label": "hUM",
"ItemValueLabel": "0005",
"Name": "hUM"
},
{
"ItemValue": "5",
"Label": "hCounty",
"ItemValueLabel": "5",
"Name": "hCounty"
}
]
},
{
"country": "USA",
"projectId": "USAID2020",
"case": "2014",
"recordType": "Eligibility",
"itemDetails": [
{
"ItemValue": "023",
"Label": "hA",
"ItemValueLabel": "023",
"Name": "hA"
},
{
"ItemValue": "0005",
"Label": "hUM",
"ItemValueLabel": "0005",
"Name": "hUM"
},
{
"ItemValue": "0005",
"Label": "hPUM",
"ItemValueLabel": "0005",
"Name": "hPUM"
}
]
}
]
This is how I want the labels to appear
[
{
"country": "USA",
"projectId": "USAID2020,
"case": "2014",
"recordType": "Identification",
"itemDetails": [
{
"ItemValue": "023",
"Label": "Area Code",
"ItemValueLabel": "023",
"Name": "hA"
},
{
"ItemValue": "0005",
"Label": "Manager Identification",
"ItemValueLabel": "0005",
"Name": "hUM"
},
{
"ItemValue": "5",
"Label": "County Name",
"ItemValueLabel": "5",
"Name": "hCounty"
}
]
},
{
"country": "USA",
"projectId": "USAID2020",
"case": "2014",
"recordType": "Eligibility",
"itemDetails": [
{
"ItemValue": "023",
"Label": "Area Code",
"ItemValueLabel": "023",
"Name": "hA"
},
{
"ItemValue": "0005",
"Label": "Manager Identification",
"ItemValueLabel": "0005",
"Name": "hUM"
},
{
"ItemValue": "0005",
"Label": "House Code",
"ItemValueLabel": "0005",
"Name": "hPUM"
}
]
}
]
This is my logic
public ArrayList<Summary> getHouseHoldRecordsByCase(String country, String projectId, String case) {
ArrayList<Summary> documents= new ArrayList<>();
Summary summary = new Summary();
ArrayList<ItemDetails> details = new ArrayList<>();
COVER cover = dataStoreService.getHouseHoldRecordsByCase(country, projectId, caseNumber);
summary.case = caseNumber;
summary.recordType = "Identification";
summary.country = country;
summary.projectId = projectId;
Field[] fields = hsecover.getClass().getDeclaredFields();
for (Field _f:fields){
try {
String val = PropertyUtils.getProperty(hsecover, _f.getName()).toString();
details.add(new ItemDetails(val, _f.getName(), val, _f.getName()));
} catch (Exception e) {
e.printStackTrace();
}
}
summary.itemDetails = details;
documents.add(summary);
summary = new Summary();
ELIGILITY elig = dataStoreService.getEliByCase(country, projectId, case);
summary.recordType = "Eligibility";
summary.case = case;
summary.country = country;
summary.projectId = projectId;
details = new ArrayList<>();
fields = elig.getClass().getDeclaredFields();
for (Field _f:fields){
try {
String val = PropertyUtils.getProperty(elig, _f.getName()).toString();
details.add(new ItemDetails(val, _f.getName(), val, _f.getName()));
} catch (Exception e) {
e.printStackTrace();
}
}
summary.itemDetails = details;
documents.add(summary);
}
return documents;
}
public COVER getHouseHoldRecordsByCase(String country, String projectId, String case) {
COVER usa = cover_repository.findByCase(case);
return usa;
}
public ELIGILITY getEliByCase(String country, String projectId, String case) {
ELIGILITY usa = eligility_repository.findByCaseNumber(case);
return usa;
}
My ItemDetails model class
public class ItemDetails {
public String ItemValue;
public String Label;
public String ItemValueLabel;
public String Name;
public ItemDetails(String itemValue, String label, String itemValueLabel, String name) {
ItemValue = itemValue;
Label = label;
ItemValueLabel = itemValueLabel;
Name = name;
}
}
My Summary class
public class Summary {
public String country;
public String projectId;
public String case;
public String recordType;
public ArrayList<ItemDetails> itemDetails;
}
The data comes from a database.
How can I set the label names with names that make sense instead of coming as entity names?

You Can use #JsonProperty("different names") on each fields
Or you can use #JsonSetter("different name") on setter method level.

Related

JSON, data can have object and array and use data class for all

When trying to process JSON, I recive Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
This JSON is a client with array in data but i want to use the same data class for other for example employee, but I need that data can store different classes
{
"data": [
{
"client": "PAL",
"organization": "*",
"organization_info": {
"name": "*",
"searchKey": "0",
"id": "0"
},
"id": "*****",
"searchKey": "AJ23",
"commercialName": "MANOLO",
"fiscalName": "MANOLO",
"locations": [{
"address": "NUEVA",
"city": "SEVILLA",
"zipCode": "00000",
"country": "ES"}]
},
{
"client": "LAC",
"organization": "*",
"organization_info": {
"name": "*",
"searchKey": "0",
"id": "0"
},
"id": "*****",
"searchKey": "0ASD13",
"commercialName": "DANI",
"fiscalName": "DANI",
"locations": [{
"address": "FONTANA",
"city": "VALLADOLID",
"zipCode": "00000",
"country": "ES"
}]
}]
}
This JSON has a data object since it only has one result
{
"data": {
"client": "PAL",
"organization": "*",
"organization_info": {
"name": "*",
"searchKey": "0",
"id": "0"
},
"id": "*****",
"searchKey": "AJ2",
"commercialName": "MANOLO",
"fiscalName": "MANOLO",
"locations": [
"address": "NUEVA",
"city": "SEVILLA",
"zipCode": "00000",
"country": "ES"
}]
}
}
The idea of the Data class is that it be generic to be able to call different classes Customer, Provider, etc. from the main class.
public class Data<T> {
#SerializedName("data")
private final List<T> data;
String links;
public Data(List<T> data) {
super();
this.data = data;
}
public List<T> getData() {
return data;
}
//get and set method
public class Client {
private String client;
private String organization;
private Org_info organization_info;
private String id;
private String fiscalName;
private String searchKey;
private String commercialName;
private String phone;
private String email;
private ArrayList<Locations> locations;
public Cliente(Org_info organization_info, String client, String organization, String id, String fiscalName, String searchKey,String phone, String email,
String commercialName,ArrayList<Locations> locations) {
super();
this.organization_info=organization_info;
this.client = client;
this.organization = organization;
this.id = id;
this.fiscalName = fiscalName;
this.searchKey = searchKey;
this.commercialName = commercialName;
this.locations = locations;
}
//get and set method
How can I make the data class generic, and be able to store JSON data with the data node from both clients and providers, while receiving an array of data or a data object?
public static void main(String[] args){
conection();
InputStreamReader inputStreamReader = new InputStreamReader(http.getInputStream(), "UTF-8");
BufferedReader br = new BufferedReader(inputStreamReader);
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = br.read()) != -1) {
sb.append((char) cp);
}
String output = sb.toString();
final Type tpEnvClient = new TypeToken<Data<Client>>(){}.getType();
final Data<Client> envEmp = new Gson().fromJson(output, tpEnvClient);
When trying to store an array I get an error because I can't store a list of clients.

parse json from sharepoint?

I have a response received from sharepoint.
{
"d": {
"query": {
"SecondaryQueryResults": {
"__metadata": {
"type": "Collection(Microsoft.Office.Server.Search.REST.QueryResult)"
},
"results": []
},
"SpellingSuggestion": "",
"TriggeredRules": {
"__metadata": {
"type": "Collection(Edm.Guid)"
},
"results": ["e0205660-4971-4574-aa40-af6b4383cadd"]
},
"ElapsedTime": 224,
"__metadata": {
"type": "Microsoft.Office.Server.Search.REST.SearchResult"
},
"Properties": {
"__metadata": {
"type": "Collection(SP.KeyValue)"
},
"results": [{
"ValueType": "Edm.Int32",
"Value": "10",
"Key": "RowLimit"
}, {
"ValueType": "Edm.Guid",
"Value": "8413cd39-2156-4e00-b54d-11efd9abdb49",
"Key": "SourceId"
}, {
"ValueType": "Edm.Guid",
"Value": "7bc4ba9e-80ff-7000-58cf-f7ac556d1e34",
"Key": "CorrelationId"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "WasGroupRestricted"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "IsPartial"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "HasParseException"
}, {
"ValueType": "Edm.String",
"Value": "en",
"Key": "WordBreakerLanguage"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "IsPartialUpnDocIdMapping"
}, {
"ValueType": "Edm.Boolean",
"Value": "true",
"Key": "EnableInterleaving"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "IsMissingUnifiedGroups"
}, {
"ValueType": "Edm.String",
"Value": "i62456",
"Key": "Constellation"
}, {
"ValueType": "Edm.String",
"Value": "<Query Culture=\"en-US\" EnableStemming=\"True\" EnablePhonetic=\"False\" EnableNicknames=\"False\" IgnoreAllNoiseQuery=\"True\" SummaryLength=\"180\" MaxSnippetLength=\"180\" DesiredSnippetLength=\"90\" KeywordInclusion=\"0\" QueryText=\"59055305\" QueryTemplate=\"\" TrimDuplicates=\"True\" Site=\"e297bd2b-597a-4f54-8509-e2febb91b869\" Web=\"d42ff0d1-883b-4545-ab6a-97b0401025d4\" KeywordType=\"True\" HiddenConstraints=\"\" \/>",
"Key": "SerializedQuery"
}]
},
"PrimaryQueryResult": {
"RefinementResults": null,
"SpecialTermResults": null,
"QueryId": "0585a5f1-89bc-43c1-b736-e163b4d7c1dd",
"QueryRuleId": "00000000-0000-0000-0000-000000000000",
"CustomResults": {
"__metadata": {
"type": "Collection(Microsoft.Office.Server.Search.REST.CustomResult)"
},
"results": []
},
"__metadata": {
"type": "Microsoft.Office.Server.Search.REST.QueryResult"
},
"RelevantResults": {
"Table": {
"__metadata": {
"type": "SP.SimpleDataTable"
},
"Rows": {
"results": [{
"__metadata": {
"type": "SP.SimpleDataRow"
},
"Cells": {
"results": [{
"ValueType": "Edm.Double",
"Value": "26.8860855102549",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Rank"
}, {
"ValueType": "Edm.Int64",
"Value": "17594532057853",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "DocId"
}, {
"ValueType": "Edm.Int64",
"Value": "17594531057253",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "WorkId"
}, {
"ValueType": "Edm.String",
"Value": "Customer Request Filling",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Title"
}, {
"ValueType": "Edm.String",
"Value": "Technology Services;svc ECMWise",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Author"
}, {
"ValueType": "Edm.Int64",
"Value": "97182",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Size"
}, {
"ValueType": "Edm.String",
"Value": "https:\/\/xxxxxx.sharepoint.com\/sites\/news\/CUST\/Forms\/Appeals\/Customer Reader.pdf",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Path"
}, {
"ValueType": "Null",
"Value": null,
"__metadata": {
"type": "SP.KeyValue"
},
....
What I am trying to get is the "Path" of "Value" string of that pdf as a snapshot from below (part of section from what was above)
{
"ValueType": "Edm.String",
"Value": "https:\/\/xxxxxx.sharepoint.com\/sites\/news\/CUST\/Forms\/Appeals\/Customer Reader.pdf",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Path"
}
I have tried to use JSONObject to parse it like this.
JSONObject jsonObject = (JSONObject) parser.parse(new InputStreamReader((httpConn.getInputStream())));
JSONObject folder = (JSONObject)jsonObject.get("d");
JSONObject query = (JSONObject) folder.get("query");
JSONObject properties = (JSONObject) query.get("PrimaryQueryResult");
JSONObject result = (JSONObject) properties.get("RelevantResults");
JSONObject table = (JSONObject) result.get("Table");
JSONObject rows = (JSONObject) table.get("Rows");
....
I was wondering if there is a easier way to do this or what if one of the key is not populated. It would throw null pointer exception so is there a way just to find a key directly inside of this long nested json and how do I get the field "Key" from the json array of the "Cells"
You should consider using a JSON serializer such as Jackson or GSON.
If the underlying JSON response structure will be the same for each call, even if it has missing keys, you can create your own POJO using something like JSONSchema2POJO. This will generate a POJO with Jackson or GSON annotations using a JSON string that you provide. Here's an example using a snippet of your JSON string:
-----------------------------------com.example.Example.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("ValueType")
#Expose
private String valueType;
#SerializedName("Value")
#Expose
private String value;
#SerializedName("__metadata")
#Expose
private Metadata metadata;
#SerializedName("Key")
#Expose
private String key;
public String getValueType() {
return valueType;
}
public void setValueType(String valueType) {
this.valueType = valueType;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Metadata getMetadata() {
return metadata;
}
public void setMetadata(Metadata metadata) {
this.metadata = metadata;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
-----------------------------------com.example.Metadata.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Metadata {
#SerializedName("type")
#Expose
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
This is standard practice when consuming JSON in Java and it allows keys/values to be null when the object is serialized without breaking your code.
If the JSON structure is completely unpredictable, GSON allows you to create Generic types or you can take it a step further and write custom serializers. Jackson likely has similar functionality but I'm only versed in GSON.
You could use quick-json (enter link description here) and have something like this (rapid version not optimized) :
public class Go {
public static void main(String[] args) {
try {
List<String> pdf_list = new ArrayList<>();
JsonParserFactory factory= JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson("/54424034/sharepoint.json", "UTF-8");
//jsonMap.get("d/query/PrimaryQueryResult/RelevantResults/Table/Rows/results");
Map d = (Map) jsonMap.get("d");
Map query = (Map) d.get("query");
Map primaryQueryResult = (Map) query.get("PrimaryQueryResult");
Map relevantResults = (Map) primaryQueryResult.get("RelevantResults");
Map table = (Map) relevantResults.get("Table");
Map rows = (Map) table.get("Rows");
List<Map> results_rows = (ArrayList) rows.get("results");
for (Map result_row : results_rows) {
Map cells = (Map) result_row.get("Cells");
List<Map> results_cells = (ArrayList) cells.get("results");
for (Map result_cell : results_cells) {
String key = (String) result_cell.get("Key");
if ("Path".equalsIgnoreCase(key)) {
pdf_list.add((String) result_cell.get("Value"));
}
}
}
System.out.println(pdf_list);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
It just parses your Json and add all pdf path into a List

Recursive JSON data parsing using GSON

Sometime we may have JSON data like,
[
{
"Name": "Fruits",
"Quantity": "10",
"isCheckBox": false,
"List": [
{
"Name": "Mango",
"Quantiy": "10",
"iScheckBox": true,
"List": null
},
{
"Name": "Apple",
"Quantiy": "10",
"iScheckBox": false,
"List": [
{
"Name": "Simla",
"Quantiy": "10",
"iScheckBox": true,
"List": null
},
{
"Name": "Fuji",
"Quantiy": "10",
"iScheckBox": false,
"List": []
}
]
}
]
},
{
"Name": "Fruits",
"Quantity": "10",
"isCheckBox": false,
"List": [
{
"Name": "Mango",
"Quantiy": "10",
"iScheckBox": true,
"List": null
},
{
"Name": "Apple",
"Quantiy": "10",
"iScheckBox": false,
"List": [
{
"Name": "Simla",
"Quantiy": "10",
"iScheckBox": true,
"List": null
},
{
"Name": "Fuji",
"Quantiy": "10",
"iScheckBox": false,
"List": []
}
]
}
]
}
]
Note : If the isCheckBox value is false then will check the list values to get the inner objects.
Don't know the end of depth level, it may end, or goes on. How to define the POJO class for JSON data like this?
public class Shopping
{
private Fruits Fruits;
private String Vegetables;
public Fruits getFruits ()
{
return Fruits;
}
public void setFruits (Fruits Fruits)
{
this.Fruits = Fruits;
}
public String getVegetables ()
{
return Vegetables;
}
public void setVegetables (String Vegetables)
{
this.Vegetables = Vegetables;
}
#Override
public String toString()
{
return "ClassPojo [Fruits = "+Fruits+", Vegetables = "+Vegetables+"]";
}}
This will be enough for the above given sample. Please try
Actually the solution is very simple,
Here is entity,
public class FruitsEntity {
String Name;
String Quantity;
boolean isCheckBox;
ArrayList<FruitsEntity> List;
}
And you can parse using,
Gson gson = new Gson();
ArrayList<FruitsEntity> nestEntities = gson.fromJson(jsonData, new TypeToken<ArrayList<FruitsEntity>>() {
}.getType());

RETROFIT 2.0 unbale to acess api response data contains any list

Hi guys i have struck with one problem while i am trying to access one api services it is all working fine. But my issue iin processing the response .
I am using retrofit 2.0
Below is my json response for my api
{
"status": 200,
"success": "true",
"data": [
{
"works_node": [
{
"works_items": [
{
"work_id": "number",
"preference": "number",
"Task_created_time": "datetime yyyy-mm-dd h:m:s"
}
]
}
],
"questions_node": [
{
"questions_items": [
{
"q_id": "number",
"work_id": "number",
"question_text": "string",
"preference": "number"
}
]
}
],
"answers_node": [
{
"answers_items": [
{
"a_id": "number",
"q_id": "number",
"answer_text": "string",
"prefernce": "number",
"point": "number",
"is_suggest": "number",
"work_id": "number"
}
]
}
],
"answer_suggestions_node": [
{
"answer_suggestions_items": [
{
"a_id": "number",
"q_id": "number",
"answer_suggestion_text": "string",
"point": "number",
"work_id": "number"
}
]
}
]
}
]
}
Below is the api calling code
public void getWorkTaskConfig(){
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
String DeviceImei=uf.getIMEI();
int userId=db.getUserId();
Call<WorkTaskConfig> call = apiService.getWorkTaskConfig
(new BasicData(new UserInfo(userId),new DeviceInfo(DeviceImei)));
call.enqueue(new Callback<WorkTaskConfig>() {
#Override
public void onResponse(Call<WorkTaskConfig> call, Response<WorkTaskConfig> response) {
try {
int apiStatus= response.body().getStatus();
Boolean apiSuccess=response.body().getSuccess();
if (apiStatus == Constants.RESULT_CODE_OK &&
apiSuccess.equals(Constants.RESULT_SUCCESS_OK)) { //data received successfully
List<Datum> apiAllWorkTaskConfigData=response.body().getData();
List<WorksNode> apiAllWorksNodeData=response.body().getData().getWorksNode(); // im facing
//the problem here ie i am not able to access the getWorksNode() function
//in Datum.java class.
}else{ //while retrieving data something went wrong.
}
} catch (Exception e) { e.printStackTrace(); }
}
#Override
public void onFailure(Call<WorkTaskConfig> call, Throwable t) { }
});
}
WorkTaskConfig.java
public class WorkTaskConfig {
#SerializedName("status")
#Expose
private Integer status;
#SerializedName("success")
#Expose
private Boolean success;
#SerializedName("data")
#Expose
private List<Datum> data = null;
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public List<Datum> getData() {
return data;
}
public void setData(List<Datum> data) {
this.data = data;
}
}
Datum.java
public class Datum {
#SerializedName("works_node")
#Expose
private List<WorksNode> worksNode = null;
public List<WorksNode> getWorksNode() {
return worksNode;
}
public void setWorksNode(List<WorksNode> worksNode) {
this.worksNode = worksNode;
}
}
Solution
Edit Json structure
Edit POJO class(Datum)
Edit Json Structure
data is an object, not array.
{
"status": 200,
"success": "true",
"data": {
"works_node": [{
"works_items": [{
"work_id": "number",
"preference": "number",
"Task_created_time": "datetime yyyy-mm-dd h:m:s"
}]
}],
"questions_node": [{
"questions_items": [{
"q_id": "number",
"work_id": "number",
"question_text": "string",
"preference": "number"
}]
}],
"answers_node": [{
"answers_items": [{
"a_id": "number",
"q_id": "number",
"answer_text": "string",
"prefernce": "number",
"point": "number",
"is_suggest": "number",
"work_id": "number"
}]
}],
"answer_suggestions_node": [{
"answer_suggestions_items": [{
"a_id": "number",
"q_id": "number",
"answer_suggestion_text": "string",
"point": "number",
"work_id": "number"
}]
}]
}
}
Edit POJO class
go to link below and generate the pojo class again.
http://www.jsonschema2pojo.org/
And Try this.
WorkTaskConfig taskConfig = reponse.body();
List<WorksNode> worksNode = taskConfig.getData().getWorksNode();
List<QuestionsNode> questionsNode = taskConfig.getData().getQuestionsNode();
List<AnswersNode> answersNode = taskConfig.getData().getAnswersNode();
List<AnswerSuggestionsNode> answerSuggestionsNode = taskConfig.getData().getAnswerSuggestionsNode();
Replace all WorkTaskConfig to JsonElement if you are facing some problem .
and Parse manually with Gson like..
String apiAllWorkTaskConfigData = response.body().getData();
WorkTaskConfig mWorkTaskConfig = new Gson.fromJson(apiAllworkTaskConfigData,WorkTaskConfig.class);

Custom deserializer or different class design Retrofit

Retrofit makes things so easy for a noob like me. However, the API response structure that I'm requesting for my current project doesn't follow the same format as I have used before. I am unsure of whether I need to rewrite my POJO or make a custom deserializer in GSON. I cannot change the JSON structure and a custom deserializer seems daunting to me.
Here is the JSON:
{
"Green Shirt": [
{
"id": "740",
"name": “Nice Green Shirt",
"quantity": "0",
"make": "",
"model": "",
"price": “15.00",
"size": "XXS",
"sku": null,
"image": "https:\/\/google.com\/green_shirt.jpg",
"new_record": false,
"category_name": "",
"bar_code": "",
},
{
"id": "743",
"name": "Green Shirt",
"quantity": “68",
"make": "",
"model": "",
"price": “20.00",
"size": "XS",
"sku": null,
"image": "https:\/\/google.com\/green_shirt.jpg",
"new_record": false,
"category_name": "",
"bar_code": "",
}
],
"Dark Blue Jeans": [
{
"id": "1588",
"name": "Dark Blue Jeans",
"quantity": "0",
"make": "",
"model": "",
"price": "0.00",
"size": “S",
"sku": null,
"image": "https:\/\/google.com\/dark_blue_jeans.jpg",
"new_record": false,
"category_name": "",
"bar_code": "",
"category": null
},
{
"id": "1559",
"name": "Dark Blue Jeans",
"quantity": "4",
"make": "",
"model": "",
"price": "0.00",
"size": “XL",
"sku": null,
"image": "https:\/\/google.com\/dark_blue_jeans.jpg",
"new_record": false,
"category_name": "",
"bar_code": "",
"category": null
}
],
"White Belt": [
{
"id": "1536",
"name": "White Belt",
"quantity": "37",
"make": "",
"model": "",
"price": "0.00",
"size": "One Size",
"sku": null,
"image": "https:\/\/google.com\/white_belt.jpg",
"new_record": false,
"category_name": "",
"bar_code": "",
"category": null
}
]
}
Here is the POJO:
public class Product
{
private String model;
private String bar_code;
private String image;
private null sku;
private String new_record;
private String size;
private String id;
private null category;
private String price;
private String category_name;
private String name;
private String quantity;
private String make;
public String getModel ()
{
return model;
}
public void setModel (String model)
{
this.model = model;
}
public String getBar_code ()
{
return bar_code;
}
public void setBar_code (String bar_code)
{
this.bar_code = bar_code;
}
public String getImage ()
{
return image;
}
public void setImage (String image)
{
this.image = image;
}
public null getSku ()
{
return sku;
}
public void setSku (null sku)
{
this.sku = sku;
}
public String getNew_record ()
{
return new_record;
}
public void setNew_record (String new_record)
{
this.new_record = new_record;
}
public String getSize ()
{
return size;
}
public void setSize (String size)
{
this.size = size;
}
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
public null getCategory ()
{
return category;
}
public void setCategory (null category)
{
this.category = category;
}
public String getPrice ()
{
return price;
}
public void setPrice (String price)
{
this.price = price;
}
public String getCategory_name ()
{
return category_name;
}
public void setCategory_name (String category_name)
{
this.category_name = category_name;
}
public String getName ()
{
return name;
}
public void setName (String name)
{
this.name = name;
}
public String getQuantity ()
{
return quantity;
}
public void setQuantity (String quantity)
{
this.quantity = quantity;
}
public String getMake ()
{
return make;
}
public void setMake (String make)
{
this.make = make;
}
#Override
public String toString()
{
return "ClassPojo [model = "+model+", bar_code = "+bar_code+", image = "+image+", sku = "+sku+", new_record = "+new_record+", size = "+size+", id = "+id+", category = "+category+", price = "+price+", category_name = "+category_name+", name = "+name+", quantity = "+quantity+", make = "+make+"]";
}
}
Here is the request and Retrofit interface:
public static void requestData(String username,String password) {
RestAdapter.Builder builder = new RestAdapter.Builder()
.setClient(new OkClient(new OkHttpClient()))
.setEndpoint(ENDPOINT);
if (username != null && password != null) {
// concatenate username and password with colon for authentication
final String credentials = username + ":" + password;
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
// create Base64 encodet string
String string = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
request.addHeader("Accept", "application/json");
request.addHeader("Authorization", string);
}
});
}
RestAdapter adapter = builder.build();
ProductAPI api = adapter.create(ProductAPI.class);
api.getInventory(new Callback<List<Product>>() {
#Override
public void success(List<Product> products, Response response) {
Log.d(TAG, response.getUrl());
Log.d(TAG, response.getReason());
mInventory = product;
}
#Override
public void failure(RetrofitError error) {
Log.d(TAG,error.getMessage());
}
});
}
public interface ProductAPI {
#GET("/v2/get-inventory")
public void getInventory(Callback<List<Product>> response);
}
This is the error I get because the JSON starts with '{' instead of '['
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
Your JSON is invalid, try formatting it properly first before doing anything else.
Properly formatted:
{
"Green Shirt": [
{
"id": "740",
"name": "Nice Green Shirt",
"quantity": "0",
"make": "",
"model": "",
"price": "15.00",
"size": "XXS",
"sku": null,
"image": "https:\\/\\/google.com\\/green_shirt.jpg",
"new_record": false,
"category_name": "",
"bar_code": ""
},
{
"id": "743",
"name": "Green Shirt",
"quantity": "68",
"make": "",
"model": "",
"price": "20.00",
"size": "XS",
"sku": null,
"image": "https:\\/\\/google.com\\/green_shirt.jpg",
"new_record": false,
"category_name": "",
"bar_code": ""
}
],
"Dark Blue Jeans": [
{
"id": "1588",
"name": "Dark Blue Jeans",
"quantity": "0",
"make": "",
"model": "",
"price": "0.00",
"size": "S",
"sku": null,
"image": "https:\\/\\/google.com\\/dark_blue_jeans.jpg",
"new_record": false,
"category_name": "",
"bar_code": "",
"category": null
},
{
"id": "1559",
"name": "Dark Blue Jeans",
"quantity": "4",
"make": "",
"model": "",
"price": "0.00",
"size": "XL",
"sku": null,
"image": "https:\\/\\/google.com\\/dark_blue_jeans.jpg",
"new_record": false,
"category_name": "",
"bar_code": "",
"category": null
}
],
"White Belt": [
{
"id": "1536",
"name": "White Belt",
"quantity": "37",
"make": "",
"model": "",
"price": "0.00",
"size": "One Size",
"sku": null,
"image": "https:\\/\\/google.com\\/white_belt.jpg",
"new_record": false,
"category_name": "",
"bar_code": "",
"category": null
}
]
}
Some of the errors it had:
Error:Strings should be wrapped in double quotes.[Code 17, Structure 12]
Error:Strings should be wrapped in double quotes.[Code 17, Structure 28]
Error:Invalid comma, expecting }.[Code 141, Structure 53]
Error:Expecting string, not }.[Code 8, Structure 54]
Error:Strings should be wrapped in double quotes.[Code 17, Structure 67]
Error:Strings should be wrapped in double quotes.[Code 17, Structure 79]
Error:Invalid comma, expecting }.[Code 141, Structure 104]
Error:Expecting string, not }.[Code 8, Structure 105]
Error:Strings should be wrapped in double quotes.[Code 17, Structure 138]
Error:Strings should be wrapped in double quotes.[Code 17, Structure 192]
The problem seems exactly what it says. The response is an object that has an array and not an array directly:
{ [{},{},{}] }
If the response was:
[{},{},{}]
It would work, but as you cannot change the response format you should change your java. Instead of expecting a List of Products you should have an object that has a List of Products inside. That is how retrofit will map it.
Edit:
The response is actually as follows:
{[],[],[]}
Is not a list, is an object composed with three Lists of Objects Product
The mapping to an object will have to be:
public class Wrapper
{
List<Product> WhiteBelt;
List<Product> DarkBlueJeans;
List<Product> GreenShirt;
}
Something like that would be your structure. I dont believe is right, because you usally want a list and not an object with three lists inside "hardcoded".
Let me know if it helps
Edited:
So you need somthing like this:
{
"products":
[{ "name" : "Green Shirt"
"items":
[{"id": "740",
"name": “Nice Green Shirt",
"quantity": "0",
"make": "",
"model": "",
"price": “15.00",
"size": "XXS",
"sku": null,
"image": "https:\/\/google.com\/green_shirt.jpg",
"new_record": false,
"category_name": "",
"bar_code": ""
}]
}]
}
That would be a structure that accepts a list of Products and inside each prodcut you have the list of items (the one you already have).
In Java:
public class ProductList
{
List <ProductList> productList;
}
public class ProductList
{
String name;
List<Product> items;
}
Using your original Product class
I told Retrofit (GSON?) to look for a Map<String,List<Product>> instead of just a List<Product> and it figured it out, how convenient.
:
api.getInventory(new Callback<Map<String,List<Product>>>() {
#Override
public void success(Map<String,List<Product>> products, Response response) {
mInventory = products;
}
#Override
public void failure(RetrofitError error) {
Log.d(TAG,error.getMessage());
}
});
public interface ProductAPI {
#GET("/v2/get-inventory")
public void getInventory(Callback<Map<String,List<Product>>> response);
}

Categories

Resources