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

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.

Related

I'm trying to deserialize a Json using ObjectMapper but it fails to deserialize date value

Solve it by replacing all Date types to String
It's a JSON from marvel comics API I'm trying to deserialize and I'm getting
"com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance
of `com.example.demo.json2csharp.Date` (although at least one Creator exists):
no String-argument constructor/factory method to deserialize from String value
('2019-11-07T08:46:15-0500')"
, example of JSON:
{
"code": 200,
"status": "Ok",
"copyright": "© 2021 MARVEL",
"attributionText": "Data provided by Marvel. © 2021 MARVEL",
"attributionHTML": "Data provided by Marvel. © 2021 MARVEL",
"etag": "f712574873e89d0505dc68a908170fb7970d2f13",
"data": {
"offset": 0,
"limit": 20,
"total": 1,
"count": 1,
"results": [
{
"id": 82967,
"digitalId": 0,
"title": "Marvel Previews (2017)",
"issueNumber": 0,
"variantDescription": "",
"description": null,
"modified": "2019-11-07T08:46:15-0500",
"isbn": "",
"upc": "75960608839302811",
"diamondCode": "",
"ean": "",
"issn": "",
"format": "",
"pageCount": 112,
"textObjects": [
],
"resourceURI": "http://gateway.marvel.com/v1/public/comics/82967",
"urls": [
{
"type": "detail",
"url": "http://marvel.com/comics/issue/82967/marvel_previews_2017?utm_campaign=apiRef&utm_source=9a0517af422c1dfbe132dbaf086fa7f7"
}
],
"series": {
"resourceURI": "http://gateway.marvel.com/v1/public/series/23665",
"name": "Marvel Previews (2017 - Present)"
},
"variants": [
{
"resourceURI": "http://gateway.marvel.com/v1/public/comics/82965",
"name": "Marvel Previews (2017)"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/comics/82970",
"name": "Marvel Previews (2017)"
}
],
"collections": [
],
"collectedIssues": [
],
"dates": [
{
"type": "onsaleDate",
"date": "2099-10-30T00:00:00-0500"
},
{
"type": "focDate",
"date": "2019-10-07T00:00:00-0400"
}
],
"prices": [
{
"type": "printPrice",
"price": 0
}
],
"thumbnail": {
"path": "http://i.annihil.us/u/prod/marvel/i/mg/b/40/image_not_available",
"extension": "jpg"
},
"images": [
],
"creators": {
"available": 1,
"collectionURI": "http://gateway.marvel.com/v1/public/comics/82967/creators",
"items": [
{
"resourceURI": "http://gateway.marvel.com/v1/public/creators/10021",
"name": "Jim Nausedas",
"role": "editor"
}
],
"returned": 1
},
"characters": {
"available": 0,
"collectionURI": "http://gateway.marvel.com/v1/public/comics/82967/characters",
"items": [
],
"returned": 0
},
"stories": {
"available": 2,
"collectionURI": "http://gateway.marvel.com/v1/public/comics/82967/stories",
"items": [
{
"resourceURI": "http://gateway.marvel.com/v1/public/stories/183698",
"name": "cover from Marvel Previews (2017)",
"type": "cover"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/stories/183699",
"name": "story from Marvel Previews (2017)",
"type": "interiorStory"
}
],
"returned": 2
},
"events": {
"available": 0,
"collectionURI": "http://gateway.marvel.com/v1/public/comics/82967/events",
"items": [
],
"returned": 0
}
}
]
}
}
My Date class, like all the others class used in ObjectMapper, was generated at https://json2csharp.com/json-to-pojo:
public class Date {
#JsonProperty("type")
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
String type;
#JsonProperty("date")
public Date getDate() {
return this.date;
}
public void setDate(Date date) {
this.date = date;
}
Date date;
public Date() {
}
}
The method calling the mapper is this:
#PostMapping
public Root getComic(#RequestBody ComicPostRequestBody comicPostRequestBody) throws NoSuchAlgorithmException, URISyntaxException, IOException {
URI uri = comicService.makeUrl(comicPostRequestBody.getComicId());
String json = client.getComic(uri);
ObjectMapper mapper = new ObjectMapper();
Root comicWrapper = mapper.readValue(json, Root.class);
return comicWrapper;
}
Root is the Class that contains all properties
public class Root {
int code;
String status;
String copyright;
String attributionText;
String attributionHTML;
String etag;
Data data;
#JsonProperty("code")
public int getCode() {
return this.code;
}
public void setCode(int code) {
this.code = code;
}
#JsonProperty("status")
public String getStatus() {
return this.status;
}
public void setStatus(String status) {
this.status = status;
}
#JsonProperty("copyright")
public String getCopyright() {
return this.copyright;
}
public void setCopyright(String copyright) {
this.copyright = copyright;
}
#JsonProperty("attributionText")
public String getAttributionText() {
return this.attributionText;
}
public void setAttributionText(String attributionText) {
this.attributionText = attributionText;
}
#JsonProperty("attributionHTML")
public String getAttributionHTML() {
return this.attributionHTML;
}
public void setAttributionHTML(String attributionHTML) {
this.attributionHTML = attributionHTML;
}
#JsonProperty("etag")
public String getEtag() {
return this.etag;
}
public void setEtag(String etag) {
this.etag = etag;
}
#JsonProperty("data")
public Data getData() {
return this.data;
}
public void setData(Data data) {
this.data = data;
}
public Root() {
}
}
My final goal is to create a comic with:
results.id
results.title
results.description
results.isbn
results.price
I'm new to programming at all and the way I found to do it was to deserialize all the json into a Root, so I can get all these properties like root.getData().getResults()
If there's a simple way to solve this or to deserialize this JSON I'll be glad to know
Thanks

Exclude fields in json Using Jackson and Json-View

I am using json-view to create a dynamic json as per my need ,it is a great library ,I am using this library for a while now .
Recently I am facing a problem with my one of the Use cases, let me place my code first
User class
public class User {
private String name;
private String emailId;
private String mobileNo;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getMobileNo() {
return mobileNo;
}
public void setMobileNo(String mobileNo) {
this.mobileNo = mobileNo;
}
}
ScreenInfoPojo class
public class ScreenInfoPojo {
private Long id;
private String name;
private ScreenInfoPojo parentScreen;
private User createdBy;
private User lastUpdatedBy;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ScreenInfoPojo getParentScreen() {
return parentScreen;
}
public void setParentScreen(ScreenInfoPojo parentScreen) {
this.parentScreen = parentScreen;
}
public User getCreatedBy() {
return createdBy;
}
public void setCreatedBy(User createdBy) {
this.createdBy = createdBy;
}
public User getLastUpdatedBy() {
return lastUpdatedBy;
}
public void setLastUpdatedBy(User lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
Run code
public class TestMain {
public static void main(String[] args) throws JsonProcessingException {
User user=new User();
user.setName("ABC");
user.setEmailId("dev#abc123.com");
user.setMobileNo("123456789");
ScreenInfoPojo screen1=new ScreenInfoPojo();
screen1.setId(1l);
screen1.setName("Screen1");
screen1.setCreatedBy(user);
screen1.setLastUpdatedBy(user);
ScreenInfoPojo screen2=new ScreenInfoPojo();
screen2.setId(2l);
screen2.setName("Screen2");
screen2.setParentScreen(Screen1);
screen2.setCreatedBy(user);
screen2.setLastUpdatedBy(user);
ScreenInfoPojo screen3=new ScreenInfoPojo();
screen3.setId(3l);
screen3.setName("Screen3");
screen3.setParentScreen(Screen2);
screen3.setCreatedBy(user);
screen3.setLastUpdatedBy(user);
ScreenInfoPojo screen4=new ScreenInfoPojo();
screen4.setId(4l);
screen4.setName("Screen4");
screen4.setParentScreen(Screen3);
screen4.setCreatedBy(user);
screen4.setLastUpdatedBy(user);
List<ScreenInfoPojo> screens=new ArrayList<>();
screens.add(screen1);
screens.add(screen2);
screens.add(screen3);
screens.add(screen4);
ObjectMapper mapper = new ObjectMapper().registerModule(new JsonViewModule());
String json = mapper.writeValueAsString(JsonView.with(screens).onClass(ScreenInfoPojo.class, Match.match()
.exclude("*")
.include("id","name","createdBy.name","lastUpdatedBy.mobileNo","parentScreen.id")));
System.out.println("json"+json);
}
Result
[{
"id": 1,
"name": "Screen1",
"parentScreen": null,
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
}
}, {
"id": 2,
"name": "Screen2",
"parentScreen": {
"id": 1,
"name": "Screen1",
"parentScreen": null,
"createdBy": {},
"lastUpdatedBy": {}
},
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
}
}, {
"id": 3,
"name": "Screen3",
"parentScreen": {
"id": 2,
"name": "Screen2",
"parentScreen": {
"id": 1,
"name": "Screen1",
"parentScreen": null,
"createdBy": {},
"lastUpdatedBy": {}
},
"createdBy": {},
"lastUpdatedBy": {}
},
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
}
}, {
"id": 4,
"name": "Screen4",
"parentScreen": {
"id": 3,
"name": "Screen3",
"parentScreen": {
"id": 2,
"name": "Screen2",
"parentScreen": {
"id": 1,
"name": "Screen1",
"parentScreen": null,
"createdBy": {},
"lastUpdatedBy": {}
},
"createdBy": {},
"lastUpdatedBy": {}
},
"createdBy": {},
"lastUpdatedBy": {}
},
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
}
}]
Expected Result
[{
"id": 1,
"name": "Screen1",
"parentScreen": null,
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
}
}, {
"id": 2,
"name": "Screen2",
"parentScreen": {
"id": 1
},
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
}
}, {
"id": 3,
"name": "Screen3",
"parentScreen": {
"id": 2
},
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
}
}, {
"id": 4,
"name": "Screen4",
"parentScreen": {
"id": 3
},
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
}
}]
Problem
In my use case I have a class ScreenInfoPojo which refers to same class as parentScreen ,
I am trying to fetch specific field/fields of parent ( "parentScreen.id") instate I am getting all fields that I have defined on child/target Object ("id","name","createdBy.name","lastUpdatedBy.mobileNo","parentScreen.id") and parent response is again recursive ! One thing i observed that It is only happening in case of a class has its own reference , I placed User class reference as two different field createdBy and lastUpdatedBy and tried to fetch "name" and "mobileNo" respectively worked just fine.
Any suggestion to solve this problem will be really helpful !!!!
Thanks
Yes. Include clause does not work for reference to the same class.
That you can do?
Compile from source according to github instruction build from source
Update function JsonViewSerializer.JsonWriter.fieldAllowed
find:
if(match == null) {
match = this.currentMatch;
} else {
prefix = "";
}
and comment else clause
if(match == null) {
match = this.currentMatch;
} else {
//prefix = "";
}
You will get expected result. But. I do not know how it will affect another filters.
To have more control you could add property to JsonView class.
For example:
in JsonView add:
private boolean ignorePathIfClassRegistered = true;
public boolean isIgnorePathIfClassRegistered() {
return ignorePathIfClassRegistered;
}
public JsonView1<T> setIgnorePathIfClassRegistered(boolean ignorePathIfClassRegistered) {
this.ignorePathIfClassRegistered = ignorePathIfClassRegistered;
return this;
}
In JsonViewSerializer.JsonWriter.fieldAllowed function rewrite if clause to:
if(match == null) {
match = this.currentMatch;
} else {
if (result.isIgnorePathIfClassRegistered())
prefix = "";
}
And you could use it in your example like:
JsonView<List<ScreenInfoPojo>> viwevedObject = JsonView
.with(screens)
.onClass(ScreenInfoPojo.class,
Match.match()
.exclude("*")
.include("id","name")
.include("createdBy.name")
.include("lastUpdatedBy.mobileNo")
.include("parentScreen.id"))
.setIgnorePathIfClassRegistered(false);
ObjectMapper mapper = new ObjectMapper().registerModule(new JsonViewModule());
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
String json = mapper.writeValueAsString(viwevedObject);
You can simply use jackson annotation #jsonignore on the field that you do not want in the json response.
I don't know whether you can or not use any annotations on your code . If so this is useless..
The most flexible way to serialize an object is to write a custom serializer.
If I understood your requirements correctly, the following serializer might work:
public class CustomScreenInfoSerializer extends JsonSerializer<ScreenInfoPojo> {
#Override
public void serialize(ScreenInfoPojo value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException {
gen.writeStartObject();
gen.writeNumberField("id", value.getId());
gen.writeStringField("name", value.getName());
gen.writeFieldName("createdBy");
gen.writeStartObject();
gen.writeStringField("name", value.getCreatedBy().getName());
gen.writeEndObject();
gen.writeFieldName("lastUpdatedBy");
gen.writeStartObject();
gen.writeStringField("mobileNo", value.getLastUpdatedBy().getMobileNo());
gen.writeEndObject();
if (value.getParentScreen() == null) {
gen.writeNullField("parentScreen");
}
else {
gen.writeFieldName("parentScreen");
gen.writeStartObject();
gen.writeNumberField("id", value.getParentScreen().getId());
gen.writeEndObject();
}
gen.writeEndObject();
}
}
Using
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(ScreenInfoPojo.class, new CustomScreenInfoSerializer());
mapper.registerModule(module);
String json = mapper.writeValueAsString(screens);
System.out.println(json);
produces
[
{
"id": 1,
"name": "Screen1",
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
},
"parentScreen": null
},
{
"id": 2,
"name": "Screen2",
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
},
"parentScreen": {
"id": 1
}
},
{
"id": 3,
"name": "Screen3",
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
},
"parentScreen": {
"id": 2
}
},
{
"id": 4,
"name": "Screen4",
"createdBy": {
"name": "ABC"
},
"lastUpdatedBy": {
"mobileNo": "123456789"
},
"parentScreen": {
"id": 3
}
}
]

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

converting JSON to java object [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
What java class structure should I prepare to return such a JSON ?
Corrected JSON (above one is not valid) :
{
"transactionComparisonTotals": [
[
"CurrentFace",
{
"value": "1000000",
"format": "$000.00 ptr"
},
{
"value": "1000",
"format": "$000.00 ptr"
},
{
"value": "0",
"format": "$000.00 ptr"
}
],
[
"MarketPrincipal",
{
"value": "1000000",
"format": "$000.00 ptr"
},
{
"value": "1000",
"format": "$000.00 ptr"
},
{
"value": "0",
"format": "$000.00 ptr"
}
]
]
}
For this I need set of java classes. O
So one thing I can do is to produce JSON like :
{
"transactionComparisonTotals": [
{
"key": "coupon",
"valueAttributes": [
{
"value": 4.25,
"format": "00.00%",
"color": true,
"sign": true
},
{
"value": 4.26,
"format": "$00.00 %",
"color": true,
"sign": true
},
{
"value": 0.31,
"format": "00.00 bp",
"color": true,
"sign": true
}
]
}
}
But what I actually want is to have "Key" and "valueAttributes" in just one array without property (as shown in my original JSON).
Considering this json file transaction.json: (yours is not valid, so i tried to correct it just to get the idea of serialization and deserilization using gson google API).
{
"transactionComparisonTotals": [
{
"name": "CurrentFace",
"info":
[
{
"value": "1000000",
"format": "$000.00 ptr"
},
{
"value": "1000",
"format": "$000.00 ptr"
},
{
"value": "0",
"format": "$000.00 ptr"
}
]
},
{
"name": "MarketPrincipal",
"info":
[
{
"value": "1000000",
"format": "$000.00 ptr"
},
{
"value": "1000",
"format": "$000.00 ptr"
},
{
"value": "0",
"format": "$000.00 ptr"
}
]
}
]
}
Create these classes:
Data class:
public class Data{
List<TransactionComparisonTotal> transactionComparisonTotals;
public List<TransactionComparisonTotal> getTransactionComparisonTotals() {
return transactionComparisonTotals;
}
public void setTransactionComparisonTotals(
List<TransactionComparisonTotal> transactionComparisonTotals) {
this.transactionComparisonTotals = transactionComparisonTotals;
}
#Override
public String toString() {
return transactionComparisonTotals.toString();
}
}
TransactionComparisonTotal class:
public class TransactionComparisonTotal{
String name;
List<Info> info;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Info> getInfo() {
return info;
}
public void setInfo(List<Info> info) {
this.info = info;
}
#Override
public String toString() {
return "\n"+name+","+info.toString()+"\n";
}
}
Info class:
public class Info{
String value;
String format;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
#Override
public String toString() {
return value+","+format;
}
}
This is a simple example of deserilization using gson google API
public class Transaction {
public static void main(String[] args) throws JsonIOException, JsonSyntaxException, FileNotFoundException {
Gson gson = new Gson();
Data data = gson.fromJson(new BufferedReader(new FileReader(
"transaction.json")), new TypeToken<Data>() {
}.getType());
System.out.println(data);
}
}
Output:
[
CurrentFace,[1000000,$000.00 ptr, 1000,$000.00 ptr, 0,$000.00 ptr]
,
MarketPrincipal,[1000000,$000.00 ptr, 1000,$000.00 ptr, 0,$000.00 ptr]
]

How to extract the field using Gson

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;
}

Categories