How to extract the field using Gson - java

I am trying to use Gson to extract a field from a Json:
{ "attributes": { "538": { "id": "538", "code": "sabor", "label": "Sabor", "options": [ { "id": "24", "label": "Baunilha", "price": "0", "oldPrice": "0", "products": [ "1376" ] }, { "id": "25", "label": "Chocolate", "price": "0", "oldPrice": "0", "products": [ "1377" ] } ] } } }
What i need is the label field inside the options( in this case, Baunilha and Chocolate).
I tried with the following classes:
public class Customer implements Serializable{
#SerializedName("options")
private Produto options;
public Produto getOptions() {
return options;
}
public void setEmail(Produto options) {
this.options = options;
}
and
public class Produto implements Serializable{
#SerializedName("label")
private String label;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
Customer cust = g.fromJson(ja, Customer.class);
But i keep getting null pointer errors.

the "options" value is not an object consisting of a string, the "options" value is an array of objects. You need to change your definition in Customer to be:
class CustomerWrapper {
#SerializedName("attributes")
private Map<String, Customer> attributes;
}
class Customer {
#SerializedName("options")
private List<Produto> options;
}

Related

How to write complex string into Gson classes

I've been racking my brain attempting to make pojos to consume the following json string. One thing I've been doing is making multiple pojos within pojos similar to what would be necessary inside of spring boot. Not sure if this is also needed for GSON. After numerous attempts I've still havent gotten it. Thanks for any advice in advance.
Json String:
"results": [
{
"id": "superficial",
"language": "en",
"lexicalEntries": [
{
"derivatives": [
{
"id": "superficialness",
"text": "superficialness"
}
],
"entries": [
{
"etymologies": [
"late Middle English: from late Latin superficialis, from Latin superficies (see superficies)"
],
"grammaticalFeatures": [
{
"text": "Positive",
"type": "Degree"
}
],
"homographNumber": "000",
"senses": [
{
"definitions": [
"existing or occurring at or on the surface"
],
"examples": [
{
"text": "the building suffered only superficial damage"
}
],
"id": "m_en_gbus1014360.017",
"short_definitions": [
"existing or occurring at or on surface"
],
"subsenses": [
{
"definitions": [
"situated or occurring on the skin or immediately beneath it"
],
"domains": [
"Anatomy",
"Medicine"
],
"examples": [
{
"text": "the superficial muscle groups"
}
],
"id": "m_en_gbus1014360.019",
"short_definitions": [
"situated or occurring on skin or immediately beneath it"
]
},
{
"definitions": [
"appearing to be true or real only until examined more closely"
],
"examples": [
{
"text": "the resemblance between the breeds is superficial"
}
],
"id": "m_en_gbus1014360.020",
"short_definitions": [
"appearing to be true or real only until examined more closely"
],
"thesaurusLinks": [
{
"entry_id": "superficial",
"sense_id": "t_en_gb0014419.004"
}
]
},
{
"definitions": [
"not thorough, deep, or complete; cursory"
],
"examples": [
{
"text": "he had only the most superficial knowledge of foreign countries"
}
],
"id": "m_en_gbus1014360.021",
"short_definitions": [
"not thorough or complete"
],
"thesaurusLinks": [
{
"entry_id": "superficial",
"sense_id": "t_en_gb0014419.003"
}
]
},
{
"definitions": [
"not having or showing any depth of character or understanding"
],
"examples": [
{
"text": "perhaps I was a superficial person"
}
],
"id": "m_en_gbus1014360.022",
"short_definitions": [
"not having or showing any depth of character or understanding"
],
"thesaurusLinks": [
{
"entry_id": "superficial",
"sense_id": "t_en_gb0014419.006"
},
{
"entry_id": "superficial",
"sense_id": "t_en_gb0014419.002"
}
]
}
],
"thesaurusLinks": [
{
"entry_id": "superficial",
"sense_id": "t_en_gb0014419.001"
}
]
}
]
}
],
"language": "en",
"lexicalCategory": "Adjective",
"pronunciations": [
{
"dialects": [
"American English"
],
"phoneticNotation": "respell",
"phoneticSpelling": "ˌso͞opərˈfiSHəl"
},
{
"audioFile": "http://audio.oxforddictionaries.com/en/mp3/superficial_us_1.mp3",
"dialects": [
"American English"
],
"phoneticNotation": "IPA",
"phoneticSpelling": "ˌsupərˈfɪʃəl"
}
],
"text": "superficial"
}
],
"type": "headword",
"word": "superficial"
}
Pojos:
class Results {
private String id;
private String language;
private String lexicalEntries;
private String type;
private String word;
//
}
class Derivatives {
private String id;
private String text;
//
}
class Entries {
private String etymologies;
private String grammaticalFeatures;
private int homographNumber;
private List<String> senses;
//
}
public class LexicalEntries {
private Derivatives derivatives;
private List<Entries> entries;
private String language;
private String lexicalCategory;
private List<Pronunciations> pronunciations;
private String text;
//
}
public class Pronunciations {
private String dialects;
private String phoneticNotation;
private String phoneticSpelling;
//
}
class Senses {
private String definitions;
private String examples;
private String id;
private ShortDefinitions short_definitions;
private List<Subsenses> subsenses;
private List<ThesaurusLinks> thesaurusLinks;
//
}
class ShortDefinitions {
private String short_definitions;
//
}
class Subsenses {
private String definitions;
private String domains;
private String examples;
private String id;
private String shortDefinitions;
private String thesaurusLinks;
//
}
class ThesaurusLinks {
private String entry_id;
private String sense_id;
//
}
I have corrected your POJO class definitions as per your JSON.
I would recommend you reading JSON notation, how different data types are represented in it like Array/List, Object, String, int, boolean. It will clarify your understanding and you will know why your classes were not properly mapped to JSON data schema.
class Results {
private String id;
private String language;
private List<LexicalEntry> lexicalEntries;
private String type;
private String word;
//
}
public class LexicalEntry {
private List<Derivative> derivatives;
private List<Entry> entries;
private String language;
private String lexicalCategory;
private List<Pronunciation> pronunciations;
private String text;
//
}
class Derivative {
private String id;
private String text;
//
}
class Entry {
private List<String> etymologies;
private List<GrammaticalFeature> grammaticalFeatures;
private String homographNumber; //if it has quotes in JSON, it will be a string not int..JSON is a strongly typed object notation
private List<Sense> senses;
//
}
class GrammaticalFeature{
String text;
String type;
}
public class Pronunciation {
private String audioFile;
private List<String> dialects;
private String phoneticNotation;
private String phoneticSpelling;
//
}
class Sense {
private List<String> definitions;
private List<Example> examples;
private String id;
private List<String> short_definitions;
private List<Subsense> subsenses;
private List<ThesaurusLinks> thesaurusLinks;
//
}
class Example{
String text;
}
class Subsense {
private List<String> definitions;
private List<String> domains;
private List<Example> examples;
private String id;
private List<String> shortDefinitions;
private List<ThesaurusLink> thesaurusLinks;
//
}
class ThesaurusLink {
private String entry_id;
private String sense_id;
//
}

How can I convert a JSON string of objects into an ArrayList using Gson?

So I have a JSON string of countries like this:
{
"details": [
{
"country_id": "1",
"name": "Afghanistan",
"regions": null
},
{
"country_id": "2",
"name": "Albania",
"regions": null
},
{
"country_id": "3",
"name": "Algeria",
"regions": null
},
... and so on
}
Now I want to have a method that tries to convert this into an ArrayList of countries.
public static ArrayList<GFSCountry> get() {
return new Gson().fromJson(countriesJson, new TypeToken<ArrayList<GFSCountry>>(){}.getType());
}
But I get an
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path
As per request, here is my GFSCountry class:
#SerializedName("country_id")
#Expose
private String countryId;
#SerializedName("name")
#Expose
private String name;
#SerializedName("regions")
#Expose
private Object regions;
public String getCountryId() {
return countryId;
}
public void setCountryId(String countryId) {
this.countryId = countryId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getRegions() {
return regions;
}
public void setRegions(Object regions) {
this.regions = regions;
}
I know I should adjust something either from the JSON string or the method. Any help?
Since the list is nested in your JSON you will need a small mapping class that contains the list.
Try
static class GFSCountryList {
public List<GFSCountry> details;
}
public static List<GFSCountry> get() {
return new Gson().fromJson(countriesJson, GFSCountryList.class).details;
}
It seems to me that Gson is expecting your json to be like this
[
{
"country_id": "1",
"name": "Afghanistan",
"regions": null
},
{
"country_id": "2",
"name": "Albania",
"regions": null
},
{
"country_id": "3",
"name": "Algeria",
"regions": null
},
... and so on
]
But it encounters an object (marked by { })
Either you have the possibility to change your json format, or you create a class with a "details" attribut as a list to be compatible with the json's format.

how to parse json list from rest call using generic type?

I am trying to parse below json:
{
"00:00:08:00:27:5d:39:55": {
"version": "OF_13",
"port_desc": [
{
"port_number": "local",
"hardware_address": "08:00:27:5d:39:55",
"name": "flips",
"config": [
"PORT_DOWN"
],
"state": [
"LINK_DOWN"
],
"current_features": [],
"advertised_features": [],
"supported_features": [],
"peer_features": [],
"curr_speed": "0",
"max_speed": "0"
},
{
"port_number": "1",
"hardware_address": "08:00:27:5d:39:55",
"name": "eth1",
"config": [],
"state": [],
"current_features": [
"PF_1GB_FD",
"PF_COPPER",
"PF_AUTONEG"
],
"advertised_features": [
"PF_10MB_HD",
"PF_10MB_FD",
"PF_100MB_HD",
"PF_100MB_FD",
"PF_1GB_FD",
"PF_COPPER",
"PF_AUTONEG"
],
"supported_features": [
"PF_10MB_HD",
"PF_10MB_FD",
"PF_100MB_HD",
"PF_100MB_FD",
"PF_1GB_FD",
"PF_COPPER",
"PF_AUTONEG"
],
"peer_features": [],
"curr_speed": "1000000",
"max_speed": "1000000"
},
{
"port_number": "2",
"hardware_address": "08:00:27:86:14:71",
"name": "eth2",
"config": [],
"state": [],
"current_features": [
"PF_1GB_FD",
"PF_COPPER",
"PF_AUTONEG"
],
"advertised_features": [
"PF_10MB_HD",
"PF_10MB_FD",
"PF_100MB_HD",
"PF_100MB_FD",
"PF_1GB_FD",
"PF_COPPER",
"PF_AUTONEG"
],
"supported_features": [
"PF_10MB_HD",
"PF_10MB_FD",
"PF_100MB_HD",
"PF_100MB_FD",
"PF_1GB_FD",
"PF_COPPER",
"PF_AUTONEG"
],
"peer_features": [],
"curr_speed": "1000000",
"max_speed": "1000000"
},
{
"port_number": "3",
"hardware_address": "08:00:27:aa:7d:02",
"name": "eth3",
"config": [],
"state": [],
"current_features": [
"PF_1GB_FD",
"PF_COPPER",
"PF_AUTONEG"
],
"advertised_features": [
"PF_10MB_HD",
"PF_10MB_FD",
"PF_100MB_HD",
"PF_100MB_FD",
"PF_1GB_FD",
"PF_COPPER",
"PF_AUTONEG"
],
"supported_features": [
"PF_10MB_HD",
"PF_10MB_FD",
"PF_100MB_HD",
"PF_100MB_FD",
"PF_1GB_FD",
"PF_COPPER",
"PF_AUTONEG"
],
"peer_features": [],
"curr_speed": "1000000",
"max_speed": "1000000"
}
]
}
}
I am using below set of code to recieve Json from Rest:
Map<String, SwitchAllJson> switchMap = response.getEntity(new GenericType<Map<String, SwitchAllJson>>(){});
Below are my Java Classes:
public class SwitchAllJson {
private String version;
private List<PortDescriptionJson> portDesc =new ArrayList<PortDescriptionJson>();
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public List<PortDescriptionJson> getPortDesc() {
return portDesc;
}
public void setPortDesc(List<PortDescriptionJson> portDesc) {
this.portDesc = portDesc;
}
}
public class PortDescriptionJson {
private String portNumber;
private String hardwareAddress;
private String name;
private List<String> config;
private List<String> state;
private List<String> currentFeatures;
private List<String> advertisedFeatures;
private List<String> supportedFeatures;
private List<String> peerFeatures;
private String currSpeed;
private String maxSpeed;
public String getHardwareAddress(){
return this.hardwareAddress;
}
public String getPortNumber(){
return this.portNumber;
}
public void setHardwareAddress(String hardwareAddress){
this.hardwareAddress=hardwareAddress;
}
public void setPortNumber(String portNumber){
this.portNumber=portNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getConfig() {
return config;
}
public void setConfig(List<String> config) {
this.config = config;
}
public List<String> getState() {
return state;
}
public void setState(List<String> state) {
this.state = state;
}
public List<String> getCurrentFeatures() {
return currentFeatures;
}
public void setCurrentFeatures(List<String> currentFeatures) {
this.currentFeatures = currentFeatures;
}
public List<String> getAdvertisedFeatures() {
return advertisedFeatures;
}
public void setAdvertisedFeatures(List<String> advertisedFeatures) {
this.advertisedFeatures = advertisedFeatures;
}
public List<String> getSupportedFeatures() {
return supportedFeatures;
}
public void setSupportedFeatures(List<String> supportedFeatures) {
this.supportedFeatures = supportedFeatures;
}
public List<String> getPeerFeatures() {
return peerFeatures;
}
public void setPeer_features(List<String> peerFeatures) {
this.peerFeatures = peerFeatures;
}
public String getCurrSpeed() {
return currSpeed;
}
public void setCurrSpeed(String currSpeed) {
this.currSpeed = currSpeed;
}
public String getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(String maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
I am able to parse 00:00:08:00:27:5d:39:55 and version but I am getting null in port_desc. Can someone explain what I am doing wrong?
rename the properties' name to Json field names. e.g. portDesc -> port_desc

How to deserialize json with a string-url name-value pair

I have json response in the form
{
"total": 782,
"category": {
"id": 1120,
"name": "Computers & Programming"
},
"experts": [
{
"id": 385816,
"name": "Master Z",
"title": "Mr",
"description": " Expert in C++",
"profile": "http://...com/experts.svc/1.0/385816/..../json?.."
}
}
]
}
I am able to parse everything else in the experts[] array except "profile" whose value "http://...com/experts.svc/1.0/385816/..../json?.." has the following json response
{
"id": 385816,
"name": "Master Z",
"title": "",
"reviewsCount": 15359,
"averageRating": 4.87,
"status": 4,
"fee": 19.99,
"languages": "English",
"category": {
"id": 1120,
"name": "Computers & Programming"
}
}
The models used are as follows
1. main pojo:
public class ExpertObj
{
private String total;
private Category category;
private Experts[] experts;
}
Category pojo:
public class Category
{
private String id;
private String name;
}
3.Experts array pojo:
public class Experts
{
private String id;
private String name;
private String title;
private String description;
private String profile;
}
Am using Retrift 2.
private RestManager mManager;
List<Expert> mExperts = new ArrayList<>();
....
Call<ExpertsObj> call = mManager.getExpertsService().listAllExperts();
call.enqueue(new Callback<ExpertsObj>() {
#Override
public void onResponse(Call<ExpertsObj> call, Response<ExpertsObj> response) {
if (response.isSuccess()) {
ExpertsObj expertsObj = response.body();
mExperts = expertsObj.getExperts();
....}
At a loss how to parse the profile-url name-value pair and display the results in a detail layout in android.
Any help is appreciated.
New in android. Please excuse if anything is not explained properly.

Jackson ObjectMapper - readValue fails when target object has a Map field

I guess this might have been asked earlier, but could not find exactly what I was looking for. So here it goes.
My JSON looks like this -
{
"verticals": [
{
"name": "vertical1",
"icon": "icon1",
"children": []
},
{
"name": "vertical2",
"icon": "icon2",
"children": []
}
],
"config": {
"vertical1": [
{
"title": "Section1",
"icon": "icon1",
"prefs": [
{
"type": "type1",
"opts": [
{
"name": "pref_store_key",
"value": "filter-prefix-food"
}
],
"icons": [
"icon3",
"icon4"
]
},
{
"type": "type2",
"opts": [
{
"name": "pref_store_key",
"value": "filter-prefix-cue"
}
],
"icons": [
"icon5",
"icon6"
]
}
]
}
],
"vertical2": [
{
"title": "Section1",
"icon": "icon1",
"prefs": [
{
"type": "type1",
"opts": [
{
"name": "pref_store_key",
"value": "filter-prefix-food"
}
],
"icons": [
"icon3",
"icon4"
]
},
{
"type": "type2",
"opts": [
{
"name": "pref_store_key",
"value": "filter-prefix-cue"
}
],
"icons": [
"icon5",
"icon6"
]
}
]
}
]
}
}
My classes are -
public class FeatureConfigData {
private Map<String, List<ItemConfig>> config = null;
private List<Vertical> verticals = null;
public List<ItemConfig> getItemConfig(String vertical) {
if (config == null) {
return null;
} else {
return config.get(vertical);
}
}
public List<Vertical> getVerticals() {
return verticals;
}
public Map<String, List<ItemConfig>> getConfig() {
return config;
}
public void setConfig(Map<String, List<ItemConfig>> config) {
this.config = config;
}
}
public class ItemConfig {
private String title = null;
private String icon = null;
private List<Pref> prefs = null;
public static class Pref {
private String type = null;
private List<String> icons = null;
private List<Opt> opts = null;
public String getType() { return type; }
public List<String> getIcons() { return icons; }
public List<Opt> getOpts() { return opts; }
}
public static class Opt {
private String name;
private String value;
public String getName() { return name; }
public String getValue() { return value; }
}
public String getTitle() { return title; }
public String getIcon() { return icon; }
public List<Pref> getPrefs() { return prefs; }
}
I am de-serializing the json string with this -
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
FeatureConfigData config = objectMapper.readValue(json, FeatureConfigData.class);
Why is the config field coming out to be null in my case and not getting populated? Do I need to do something else to ensure that Jackson understands that map keys are "vertical1", "vertical2" etc?
Note, this configuration drives the actual name/number of the verticals. So it's not an option to replace map> with a class with fields vertical1, vertical2 etc.

Categories