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
}
}
]
Related
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
I am trying to parse JSON using GSON library.
I have a product inventory in the form of a JSON like this:
[
{
"id": 2000,
"name": "Child Shoes",
"variants": [
{
"size": "size 7",
"price": 19.99,
"tax_code": 0
}
]
},
{
"id": 3000,
"name": "Eggs",
"variants": [
{
"size": "6",
"price": 1.50,
"tax_code": 7
},
{
"size": "12",
"price": 2.25,
"tax_code": 1
}
]
},
{
"id": 3100,
"name": "Apples",
"variants": [
{
"size": "1",
"price": 0.30,
"tax_code": 7
},
{
"size": "10",
"price": 2.50,
"tax_code": 7
}
]
},
{
"id": 5423,
"name": "Book",
"variants": [
{
"size": "Assorted",
"price": 11.00,
"tax_code": 1
}
]
}
]
And Tax codes as follows :
[
{
"code": 0,
"name": "HST",
"rate": 0.13
},
{
"code": 1,
"name": "HST - Books",
"rate": 0.05
},
{
"code": 7,
"name": "EXEMPT - Food",
"rate": 0
}
]
Now, how do I generate the total bill, if I get an input like this:
[
{
"product": 3000,
"variant": 1,
"quantity": 1
},
{
"product": 3100,
"variant": 1,
"quantity": 1
}
]
I am new to JSON and having a tough time trying to identify the correct strategy to solve this problem.
I hope below solution give you some idea -
Map your json to pojo like below -
public class ProductInventory {
private Integer id;
private String name;
private List<Variant> variants = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Variant> getVariants() {
return variants;
}
public void setVariants(List<Variant> variants) {
this.variants = variants;
}
}
//class Variant
public class Variant {
private String size;
private Double price;
private Integer taxCode;
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Integer getTaxCode() {
return taxCode;
}
public void setTaxCode(Integer taxCode) {
this.taxCode = taxCode;
}
}
Use Gson library to parse json into java object and vice-versa:
Gson gson = new Gson();
Type jsonType = new TypeToken<List<ProductInventory>>(){}.getType();
List<ProductInventory> piList = gson.fromJson(json, jsonType);
Now Iterate over the piList and populate your other pojos and parse it into json using toJson() method.
Note:- You have to create pojo classes for the target json, that you can create here - http://www.jsonschema2pojo.org/
I am trying to make the Json output from Cucumber into a single Java object. This contains objects nested four levels deep, and I am having trouble deserializing it. I am presently using Jackson, but open to suggestions.
Here is my Json code:
{
"line": 1,
"elements": [
{
"line": 3,
"name": "Converteren centimeters naar voeten/inches",
"description": "",
"id": "applicatie-neemt-maten-in-cm-en-converteert-ze-naar-voet/inch,-en-vice-versa;converteren-centimeters-naar-voeten/inches",
"type": "scenario",
"keyword": "Scenario",
"steps": [
{
"result": {
"duration": 476796588,
"status": "passed"
},
"line": 4,
"name": "maak Maten-object aan met invoer in \"centimeters\"",
"match": {
"arguments": [
{
"val": "centimeters",
"offset": 37
}
],
"location": "StepDefinition.maakMatenObjectAanMetInvoerIn(String)"
},
"keyword": "Given "
},
{
"result": {
"duration": 36319,
"status": "passed"
},
"line": 5,
"name": "ik converteer",
"match": {
"location": "StepDefinition.converteerMaten()"
},
"keyword": "When "
},
{
"result": {
"duration": 49138,
"status": "passed"
},
"line": 6,
"name": "uitvoer bevat maat in \"voeten/inches\"",
"match": {
"arguments": [
{
"val": "voeten/inches",
"offset": 23
}
],
"location": "StepDefinition.uitvoerBevatMaatIn(String)"
},
"keyword": "Then "
}
]
},
{
"line": 8,
"name": "Converteren voeten/inches naar centimeters",
"description": "",
"id": "applicatie-neemt-maten-in-cm-en-converteert-ze-naar-voet/inch,-en-vice-versa;converteren-voeten/inches-naar-centimeters",
"type": "scenario",
"keyword": "Scenario",
"steps": [
{
"result": {
"duration": 84175,
"status": "passed"
},
"line": 9,
"name": "maak Maten-object aan met invoer in \"voeten/inches\"",
"match": {
"arguments": [
{
"val": "voeten/inches",
"offset": 37
}
],
"location": "StepDefinition.maakMatenObjectAanMetInvoerIn(String)"
},
"keyword": "Given "
},
{
"result": {
"duration": 23928,
"status": "passed"
},
"line": 10,
"name": "ik converteer",
"match": {
"location": "StepDefinition.converteerMaten()"
},
"keyword": "When "
},
{
"result": {
"duration": 55547,
"status": "passed"
},
"line": 11,
"name": "uitvoer bevat maat in \"centimeters\"",
"match": {
"arguments": [
{
"val": "centimeters",
"offset": 23
}
],
"location": "StepDefinition.uitvoerBevatMaatIn(String)"
},
"keyword": "Then "
}
]
}
],
"name": "Applicatie neemt maten in cm en converteert ze naar voet/inch, en vice versa",
"description": "",
"id": "applicatie-neemt-maten-in-cm-en-converteert-ze-naar-voet/inch,-en-vice-versa",
"keyword": "Feature",
"uri": "sample.feature"
}
I have tried a number of different approaches. First I used nested inner classes, but it appeared you had to make them static, which I feared would not work since I have multiple instances of the same object within one (multiple "element"-objects in the root, for example). Then I tried putting them in separate classes, with Json annotations. Here's where that got me (omitting setters):
public class CucumberUitvoer {
private String name;
private String description;
private String id;
private String keyword;
private String uri;
private int line;
#JsonProperty("elements")
private List<FeatureObject> elements;
public CucumberUitvoer(){}
}
public class FeatureObject {
private String name;
private String description;
private String id;
private String type;
private String keyword;
private int line;
#JsonProperty("steps")
private List<StepObject> steps;
public FeatureObject() {
}
}
public class StepObject {
#JsonProperty("result")
private ResultObject result;
private String name;
private String given;
private String location;
private String keyword;
private int line;
#JsonProperty("match")
private MatchObject match;
public StepObject(){}
}
public class ResultObject {
private int duration;
private String status;
public ResultObject(){}
}
public class MatchObject {
#JsonProperty("arguments")
private List<ArgumentObject> arguments;
private String location;
public MatchObject(){}
}
public class ArgumentObject {
private String val;
private String offset;
public ArgumentObject(){}
}
For clarification, here's a class diagram of how the nesting works.
This solution gives me the following error:
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of nl.icaprojecten.TestIntegratieQuintor.JSONInterpreter.CucumberUitvoer out of START_ARRAY token
Here is the code doing the actual mapping:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
CucumberUitvoer obj1 = null;
try {
obj1 = mapper.readValue(json, CucumberUitvoer.class);
} catch (IOException e) {
e.printStackTrace();
}
Is there a quick fix to this approach to make it work, or should I try something entirely different?
Ok I spent some time debugging and trying to figure out what was the problem, and finally was something pretty obvious.
implements Serializable
Thats the line I added to MatchObject and worked.
When we try to deserialize some object first we have to make those classes implements the interface Serializable
I just tried your sample code and oddly, it works.
Can you please double check your imports, if the JSON is coming in as provided and the getters, setters, constructors are actually there?
You can get the idea from this code to deserialize,
public class testCustomDeSerializer extends JsonDeserializer<test> {
public testCustomDeSerializer() {
this(null);
}
public TestCustomDeSerializer(Class t) {
// super(t);
}
#Override
public Test deserialize(JsonParser p, DeserializationContext ctx) throws IOException, JsonProcessingException {
ObjectCodec objectCodec = p.getCodec();
JsonNode node = objectCodec.readTree(p);
ObjectMapper objectMapper = new ObjectMapper();
Test test= new Test();
test.setId(node.get("line").asText());
List<elements> elementList = new ArrayList<>();
JsonNode elementsNode = node.get("elements");
Iterator<JsonNode> slaidsIterator = elementsNode.elements();
while (slaidsIterator.hasNext()) {
Steps steps= new Steps();
JsonNode slaidNode = slaidsIterator.next();
JsonNode stepNode= (JsonNode) slaidNode.get("Steps");
BoundingPoly in = objectMapper.readValue(stepNode.toString(), Steps.class);
elementsNode.setSteps(in);
/// continue
return
}
Hope it helps
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]
]
I wanted to form JSON like this:
{
"Schedule": [
{
"id": "A",
"name": "Summary",
"ischild": "1",
"level1": [
{
"id": "A.1",
"name": "A.1",
"ischild": "1",
"level2": [
{
"id": "A.1.a",
"name": "Income Statement",
"ischild": "0"
},
{
"id": "A.1.b",
"name": "Balance Sheet",
"ischild": "0"
},
{
"id": "A.1.c",
"name": "A.1.c",
"ischild": "1",
"level3": [
{
"id": "A.1.c.1",
"name": "General RWA",
"ischild": "0"
},
{
"id": "A.1.c.2",
"name": "Standardized RWA",
"ischild": "0"
},
{
"id": "A.1.c.3",
"name": "Advanced RWA",
"ischild": "0"
}
]
}
]
}
]
}
]
}
But my code is giving below output:
{
"Schedule": [
{
"name": "Summary",
"ischild": "1",
"id": "A",
"N_LEVEL": "1"
},
{
"name": "A.1",
"ischild": "1",
"id": "A.1",
"N_LEVEL": "2"
},
{
"name": "Income Statement",
"ischild": "0",
"id": "A.1.a",
"N_LEVEL": "3"
},
{
"name": "Balance Sheet",
"ischild": "0",
"id": "A.1.b",
"N_LEVEL": "3"
},
{
"name": "A.1.c",
"ischild": "1",
"id": "A.1.c",
"N_LEVEL": "3"
},
{
"name": "General RWA",
"ischild": "0",
"id": "A.1.c.1",
"N_LEVEL": "4"
},
{
"name": "Standardized RWA",
"ischild": "0",
"id": "A.1.c.2",
"N_LEVEL": "4"
},
{
"name": "Advanced RWA",
"ischild": "0",
"id": "A.1.c.3",
"N_LEVEL": "4"
}
]
}
Here is my code:
public static String getJSONFromResultSet(ResultSet rs,String keyName)
{
System.out.println(" in getJSONFromResultSet method");
Map json = new HashMap();
List list = new ArrayList();
if(rs!=null)
{
try
{
ResultSetMetaData metaData = rs.getMetaData();
while(rs.next())
{
Map<String,Object> columnMap = new HashMap<String, Object>();
for(int columnIndex=1;columnIndex<=metaData.getColumnCount();columnIndex++)
{
if(rs.getString(metaData.getColumnName(columnIndex))!=null)
columnMap.put(metaData.getColumnLabel(columnIndex),rs.getString(metaData.getColumnName(columnIndex)));
else
columnMap.put(metaData.getColumnLabel(columnIndex), "");
}
list.add(columnMap);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
json.put(keyName, list);
}
return JSONValue.toJSONString(json);
I think your target structure could be better if it's names didn't change on every level. The level number is a value not a key. ischild makes no sense either, I think this is isNotALeaf, well that can be worked out, so leave that off too, so we have:
{
"id": "A",
"name": "Summary",
"level": "1",
"children": [
{
"id": "A.1",
"name": "A.1",
"level": "2",
"children": [
{
"id": "A.1.a",
"name": "Income Statement",
"level": "3"
},
{
"id": "A.1.b",
"name": "Balance Sheet",
"level": "3"
}
]
}
}
Then generate a self-referencing class with based on that for use in GSon:
package com.example;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
#Generated("org.jsonschema2pojo")
public class Child {
#Expose
private String id;
#Expose
private String name;
#Expose
private String level;
#Expose
private List<Child> children = new ArrayList<Child>();
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 getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public List<Child_> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
this.children = children;
}
}