Gson can not parse nested string object - java

How to parse nested object
[{
"id": 100500,
"products": "[{\"id\":45,\"title\":\"All Product\"]"
}]
Model Class
public class Store {
public long id;
public List<Product> products;
}

Hi change you Gson to
{
"Id": "100500",
"products": [
{
"id": 1,
"title": "title 1"
},
{
"id": 2,
"title": "title 2"
},
{
"id": 3,
"title": "title 3"
}
]
}

No it will parse
public class Store {
public long id;
public List<Product> products;
}
Gson mGson= new Gson();
storeList=mGson.fromJson(json, Store.class);
storeList.getStores().get(0).getProducts().get(1);

Related

Build Complex JSON payload from java classes

I would like to create following json payload from the java classes. Only one condition is there, Subgroup1 can be null, meaning group may/may not have subgroup1. Not sure how can it be done. Any help would be highly appreciated. Thanks in advance! I can change the classes if needed.
{
"data" : [
{
"id": "1",
"name": "ab",
"children": [
{
"id": "1",
"name": "xyz",
"children": [
{ "id": "1",
"name": "opl"
} ]
}
]
},
{
"id":" 2",
"name": "cd",
"children": [
{
"id": "1",
"name": "ijk",
"children": [
{ "id": "1",
"name": "rty"},
{ "id": "2",
"name": "wsc"
} ]
},
{
"id": "2",
"name": "lmn",
"children": [
{ "id": "1",
"name": "qaz"},
{ "id": "2",
"name": "poi"
} ]
},
{
"id": "3",
"name": "opq",
"children": [
{ "id": "1",
"name": "edf"},
{ "id": "2",
"name": "bhgga"
} ]
}
]
},
{
"id": "3",
"name": "ef",
"children": [
{
"id": null,
"name": null,
"children": [
{ "id": "2",
"name": "ijyuht"
} ]
}
]
}
]
}
I have 3 different java classes to map objects.
Data.class
public class Data {
private Long id;
private String name;
private List<Subgroup1> children;
}
Subgroup1.class
public class Subgroup1 {
private Long id;
private String name;
private List<Subgroup2> children;
}
Subgroup2.class
public class Subgroup2 {
private Long id;
private String name;
}
Create Classes structure as below:
public class MainClass {
private List<Datum> data;
}
public class Datum {
private List<Child> children;
private String id;
private String name;
}
public class Child {
private List<Child> children;
private String id;
private String name;
}
below format you can use in Java, its just a way you can do it in multiples way, as i have expained in a easy way.
MainClass mainClass = new MainClass();
List<Child> level2List = new ArrayList<>();
Child level2Child = new Child();
level2Child.setName("opl");
level2Child.setId("1");
level2List.add(level2Child);
List<Child> childList = new ArrayList<>();
Child child = new Child();
child.setChildren(level2List);
child.setId("1");
child.setName("xyz");
childList.add(child);
Datum datum = new Datum();
datum.setChildren(childList);
datum.setId("1");
datum.setName("ab");
List<Datum> datumList = new ArrayList<>();
datumList.add(datum);
mainClass.setData(datumList);
System.out.println(new Gson().toJson(mainClass));

Java and json object

I am trying to download a JSON file with the latest news from a link, and then fill a news page with news articles from the JSON file, but I can't get it to work.
This is my JSON file:
[
"sections": {
{
"title": "category 1",
"color": 2,
"posts": [
{
"title": "Test 1",
"date": 17-09-2019,
"images": {
"launcher_preview": "testimage.png",
"imageName2": "testimage.png"
},
"href": "https://testlink.com"
},
{
"title": "Test 2",
"date": 17-09-2019,
"images": {
"launcher_preview": "testimage2.png",
"imageName2": "testiamge2.png"
},
"href": "https://testlink2.com"
}
]
},
{
"title": "category 2",
"color": 2,
"posts": [
{
"title": "Test 3",
"date": 17-09-2019,
"images": {
"launcher_preview": "testimage3.png",
"imageName2": "testimage3.png"
},
"href": "https://testlink3.com"
}
]
}
}
]
My java class (Only included the necessary part):
public class NewsFeedManager extends ImageCache {
private static final String METADATA_URL = "https://Linkhiddenforprivacy.com/news/latest.json",
IMAGE_PROVIDER_URL = "https://Linkhiddenforprivacy.com/news/images/";
private static final int CACHE_TIME = 1000 * 60 * 20;
private final ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
#JsonProperty
#Getter
private NewsFeed feed = new NewsFeed();
private Path imageCacheDir;
public NewsFeedManager() {
}
public static NewsFeedManager load(Launcher launcher) {
NewsFeedManager manager = Persistence.load(new File(launcher.getCacheDir(), "news_feed.json"), NewsFeedManager.class);
manager.imageCacheDir = Paths.get(launcher.getCacheDir().getAbsolutePath(), "launcher/news/images");
return manager;
}
public ListenableFuture<NewsFeed> refresh(boolean force) {
if (!force && this.feed != null && this.feed.expires > System.currentTimeMillis()) {
return Futures.immediateFuture(this.feed);
}
ListenableFuture<NewsFeed> future = this.executor.submit(() -> {
log.info("Fetching latest news feed from " + METADATA_URL);
NewsFeed feed = HttpRequest.get(HttpRequest.url(METADATA_URL))
.execute()
.expectResponseCode(200)
.returnContent()
.asJson(NewsFeed.class);
feed.expires = System.currentTimeMillis() + CACHE_TIME;
return feed;
});
Futures.addCallback(future, new FutureCallback<NewsFeed>() {
#Override
public void onSuccess(#Nullable NewsFeed result) {
NewsFeedManager.this.feed = result;
NewsFeedManager.this.save();
}
#Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
return future;
}
public ListenableFuture<Image> getImage(String resource) {
String remote = IMAGE_PROVIDER_URL + resource;
log.info("Fetching latest image feed from " + remote);
return this.obtain(resource, remote, false);
}
private void save() {
Persistence.commitAndForget(this);
}
public void clear() {
this.feed = null;
this.clearImageCache();
}
#Override
protected long getMaxCacheTime() {
return CACHE_TIME;
}
#Override
protected Path getImageCacheFolder() {
return this.imageCacheDir;
}
public static class NewsFeed {
#JsonProperty
#Getter
private List<NewsSection> sections;
#JsonProperty
private long expires;
}
public static class NewsSection {
#JsonProperty
#Getter
private String title;
#JsonProperty
#Getter
private int color;
#JsonProperty
#JsonManagedReference
#Getter
private List<NewsPost> posts;
}
public static class NewsPost {
#JsonProperty
#Getter
private String title;
#JsonProperty
#Getter
private Date date;
#JsonProperty
#Getter
private Map<String, String> images;
#JsonProperty
#Getter
private String href;
#JsonBackReference
#Getter
private NewsSection section;
}
I get this error when the client tries to fetch the news:
[info] Fetching latest news feed from https://linkhiddenforprivacy.com/news/latest.json
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.hiddenforprivacy.launcher.ui.resources.NewsFeedManager$NewsFeed out of START_ARRAY token
at [Source: java.io.StringReader#4ac13260; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:691)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:685)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromArray(BeanDeserializerBase.java:1215)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:126)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2986)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2091)
at com.skcraft.launcher.util.HttpRequest$BufferedResponse.asJson(HttpRequest.java:479)
at com.hiddenforprivacy.launcher.ui.resources.NewsFeedManager.lambda$refresh$0(NewsFeedManager.java:61)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
I am not sure what is causing the error, I think my JSON is not correctly formatted, but I am not sure, can anyone here see what is causing this error?
Thank you for your time,
Piet
If your object is in an array, you can't assign a key to it. As a result, your HttpRequest.asJson() is failing. I have edited your JSON to return your sections as an array of objects instead of a single array object containing the sections.
Also, you can't have dates as numbers in a JSON file. I converted them into strings as well. For standardization purposes, make sure you store the date as an ISO 8601 string in your actual file.
Try this edited version of your JSON:
[
{
"title": "category 1",
"color": 2,
"posts": [{
"title": "Test 1",
"date": "17-09-2019",
"images": {
"launcher_preview": "testimage.png",
"imageName2": "testimage.png"
},
"href": "https://testlink.com"
},
{
"title": "Test 2",
"date": "17-09-2019",
"images": {
"launcher_preview": "testimage2.png",
"imageName2": "testiamge2.png"
},
"href": "https://testlink2.com"
}
]
},
{
"title": "category 2",
"color": 2,
"posts": [{
"title": "Test 3",
"date": "17-09-2019",
"images": {
"launcher_preview": "testimage3.png",
"imageName2": "testimage3.png"
},
"href": "https://testlink3.com"
}]
}
]
[
"sections": {
{
I see two problems at the very start of the file.
One, the first character is a square bracket, indicating that the contained values will be a simple list. But then it goes straight into "sections" : {, which is a key/value syntax, indicating that we ought to be in a dictionary/hashmap context. But we aren't; we're in a list context.
Second, there are two opening braces following "sections":. What is the second one meant to indicate?
I see three problems
1. The wrong bracket around json object.
2. Sections is an array, but is missing the array syntax.
3. Date String is not a valid object type, the string should be wrapped with quotes.
Properly formatted json for an object with sections which is an array of two sections.
{"sections": [
{
"title": "category 1",
"color": 2,
"posts": [
{
"title": "Test 1",
"date": "17-09-2019",
"images": {
"launcher_preview": "testimage.png",
"imageName2": "testimage.png"
},
"href": "https://testlink.com"
},
{
"title": "Test 2",
"date": "17-09-2019",
"images": {
"launcher_preview": "testimage2.png",
"imageName2": "testiamge2.png"
},
"href": "https://testlink2.com"
}
]
},
{
"title": "category 2",
"color": 2,
"posts": [
{
"title": "Test 3",
"date": "17-09-2019",
"images": {
"launcher_preview": "testimage3.png",
"imageName2": "testimage3.png"
},
"href": "https://testlink3.com"
}
]
}]
}

Convert a Dynamic JSON String to a HashMap

I have a JSONObject with some dynamic attributes that I want to convert into a class, I have tried a lot of examples on SO, but no solution.
My json string looks like this
{
"result": {
"account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q",
"assets": {
"r9F6wk8HkXrgYWoJ7fsv4VrUBVoqDVtzkH": [
{
"currency": "BTC",
"value": "5444166510000000e-26"
}
],
"rPFLkxQk6xUGdGYEykqe7PR25Gr7mLHDc8": [
{
"currency": "EUR",
"value": "4000000000000000e-27"
}
],
"rPU6VbckqCLW4kb51CWqZdxvYyQrQVsnSj": [
{
"currency": "BTC",
"value": "1029900000000000e-26"
}
],
"rpR95n1iFkTqpoy1e878f4Z1pVHVtWKMNQ": [
{
"currency": "BTC",
"value": "4000000000000000e-30"
}
],
"rwmUaXsWtXU4Z843xSYwgt1is97bgY8yj6": [
{
"currency": "BTC",
"value": "8700000000000000e-30"
}
]
},
"balances": {
"rKm4uWpg9tfwbVSeATv4KxDe6mpE9yPkgJ": [
{
"currency": "EUR",
"value": "29826.1965999999"
}
],
"ra7JkEzrgeKHdzKgo4EUUVBnxggY4z37kt": [
{
"currency": "USD",
"value": "13857.70416"
}
]
},
"ledger_hash": "980FECF48CA4BFDEC896692C31A50D484BDFE865EC101B00259C413AA3DBD672",
"ledger_index": 14483212,
"obligations": {
"BTC": "5908.324927635318",
"EUR": "992471.7419793958",
"GBP": "4991.38706013193",
"USD": "1997134.20229482"
},
"status": "success",
"validated": true
}
}
Is there something that I can use from the json.org or ObjectMapper?
The only part that is given me problem is the assets and the balances, I will appreciate all help in right direction
You should be able to deserialize this into classes like:
public class Response {
private Result result;
}
public class Result {
private String account;
private Map<String, List<Asset>> assets;
private Map<String, List<Asset>> balances;
private String ledger_hash;
private String ledger_index;
private Map<String, String> obligations;
private String status;
private boolean validated;
}
public class Asset {
private String currency;
private String value;
}

katharsis collection of non primitives serialization

Trying to serialize a collection of non-primitive types using katharsis, but getting an empty collection all the time.
Response example:
{
"data": {
"type": "products",
"id": "1",
"attributes": {
"simpleAttributes": [
{}
],
"variationGroup": "variationGroup"
},
"relationships": {},
"links": {
"self": "http://localhost:8080/api/products/1"
}
},
"included": []
}
Expected response:
{
"data": {
"type": "products",
"id": "1",
"attributes": {
"simpleAttributes": [
{
tittle: "some title",
value: "some value"
}
],
"variationGroup": "variationGroup"
},
"relationships": {},
"links": {
"self": "http://localhost:8080/api/products/1"
}
},
"included": []
}
Domain objects (getters, setters, constructor and other stuff omitted by using lombok #Data annotation):
#JsonApiResource(type = "products")
#Data
public class Product {
#JsonApiId
private Integer id;
private List<SimpleAttribute> simpleAttributes = new ArrayList<>();
private String variationGroup;
}
#Data
public class SimpleAttribute implements Serializable{
private String title;
private String value;
}
I do not want to use relationships in this case or to include attributes to "included" field. Is it possible in katharsis?
Not sure what actually was wrong, but the problem disappeared after I changed katharsis-spring version from 2.3.0 to 2.3.1.

how to convert self iterating ArrlyList into json using Jackson [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
i want to convert List data into below json structure for this i had fetched data from mysql into arraylist and also written the pojo class EducationDTO .
{
"id": "1",
"name": "EDUCATION",
"data": "",
"children": [
{
"id": "1.1",
"name": "STREAM-ENGG",
"data": "",
"children": [
{
"id": "1.11",
"name": "COMPUTER SCIENCE",
"data": "",
"children": [
{
"id": "1.111",
"name": "YEAR-01",
"data": ""
},
{
"id": "1.112",
"name": "YEAR-02",
"data": ""
},
{
"id": "1.113",
"name": "YEAR-03",
"data": ""
},
{
"id": "1.114",
"name": "YEAR-04",
"data": ""
}
]
},
{
"id": "1.12",
"name": "EXTC",
"data": "",
"children": [
{
"id": "1.121",
"name": "YEAR-01",
"data": ""
},
{
"id": "1.122",
"name": "YEAR-02",
"data": ""
},
{
"id": "1.123",
"name": "YEAR-03",
"data": ""
},
{
"id": "1.124",
"name": "YEAR-04",
"data": ""
}
]
},
{
"id": "1.13",
"name": "BIOMEDICAL",
"data": "",
"children": [
{
"id": "1.131",
"name": "YEAR-01",
"data": ""
},
{
"id": "1.132",
"name": "YEAR-02",
"data": ""
},
{
"id": "1.133",
"name": "YEAR-03",
"data": ""
},
{
"id": "1.134",
"name": "YEAR-04",
"data": ""
}
]
},
{
"id": "1.14",
"name": "CHEMICAL",
"data": "",
"children": [
{
"id": "1.141",
"name": "YEAR-01",
"data": ""
},
{
"id": "1.142",
"name": "YEAR-02",
"data": ""
},
{
"id": "1.143",
"name": "YEAR-03",
"data": ""
},
{
"id": "1.144",
"name": "YEAR-04",
"data": ""
}
]
}
]
},
{
"id": "1.2",
"name": "STREAM-MEDICAL",
"data": "",
"children": [
{
"id": "1.21",
"name": "MBBS",
"data": "",
"children": [
{
"id": "1.211",
"name": "YEAR-01",
"data": ""
},
{
"id": "1.212",
"name": "YEAR-02",
"data": ""
},
{
"id": "1.212",
"name": "YEAR-03",
"data": ""
},
{
"id": "1.213",
"name": "YEAR-04",
"data": ""
},
{
"id": "1.214",
"name": "YEAR-05",
"data": ""
}
]
},
{
"id": "1.22",
"name": "BHMS",
"data": "",
"children": [
{
"id": "1.221",
"name": "YEAR-01",
"data": ""
},
{
"id": "1.222",
"name": "YEAR-02",
"data": ""
},
{
"id": "1.223",
"name": "YEAR-03",
"data": ""
}
]
},
{
"id": "1.31",
"name": "BDS",
"data": "",
"children": [
{
"id": "1.311",
"name": "YEAR-01",
"data": ""
},
{
"id": "1.312",
"name": "YEAR-02",
"data": ""
},
{
"id": "1.313",
"name": "YEAR-03",
"data": ""
},
{
"id": "1.314",
"name": "YEAR-04",
"data": ""
}
]
}
]
}
]
}
i am trouble of fallowing logic i have written it will contain duplicate code.
JsonFactory jFactory=new JsonFactory();
Writer writer = new StringWriter();
JsonGenerator jsGenerator = jFactory.createJsonGenerator(writer);
jsGenerator.writeStartObject();
jsGenerator.writeEndObject();
for(EducationDTO eDto:vDto.getEducationDTOList()){
if(eDto.getParent_Id().equalsIgnoreCase("0")){
jsGenerator.writeStringField("id",eDto.getUnid());
jsGenerator.writeStringField("name",eDto.getNode_Name());
jsGenerator.writeStringField("data","");
if(eDto.getHasChildren().equalsIgnoreCase("YES")){
jsGenerator.writeFieldName("children");
jsGenerator.writeStartArray();
for(EducationDTO eDto2:vDto.getEducationDTOList()){
if(eDto2.getParent_Id().equalsIgnoreCase(eDto.getUnid())){
jsGenerator.writeStartObject();
jsGenerator.writeStringField("id",eDto.getUnid());
jsGenerator.writeStringField("name",eDto2.getNode_Name());
jsGenerator.writeStringField("data","");
if(eDto2.getHasChildren().equalsIgnoreCase("YES")){
jsGenerator.writeFieldName("children");
jsGenerator.writeStartArray();
for(EducationDTO eDto3:vDto.getEducationDTOList()){
if(eDto3.getParent_Id().equalsIgnoreCase(eDto2.getUnid())){
jsGenerator.writeStartObject();
jsGenerator.writeStringField("id",eDto.getUnid());
jsGenerator.writeStringField("name",eDto3.getNode_Name());
jsGenerator.writeStringField("data","");
if(eDto2.getHasChildren().equalsIgnoreCase("YES")){
jsGenerator.writeFieldName("children");
jsGenerator.writeStartArray();
for(EducationDTO eDto4:vDto.getEducationDTOList()){
if(eDto4.getParent_Id().equalsIgnoreCase(eDto3.getUnid())){
jsGenerator.writeStartObject();
jsGenerator.writeStringField("id",eDto4.getUnid());
jsGenerator.writeStringField("name",eDto4.getNode_Name());
jsGenerator.writeStringField("data","");
jsGenerator.writeEndObject();
}
}
jsGenerator.writeEndArray();
}
jsGenerator.writeEndObject();
}
}
jsGenerator.writeEndArray();
}
jsGenerator.writeEndObject();
}
}
jsGenerator.writeEndArray();
}
break;
}
}
jsGenerator.close();
please use code like this:
import java.lang.reflect.Field;
import java.util.List;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class JsonConvertor {
private static GsonBuilder gsonBuilder;
private static Gson gson;
private JsonConvertor() {
}
public static Object fromJson(String json, Class clz)
{
gson=new Gson();
return gson.fromJson(json,clz);
}
public static String toJson(Object obj) {
gsonBuilder = new GsonBuilder();
gsonBuilder = gsonBuilder
.addSerializationExclusionStrategy(new CustomIclusionStrategy(
obj.getClass()));
gson = gsonBuilder.create();
String json = gson.toJson(obj);
return json;
}
}
class CustomIclusionStrategy implements ExclusionStrategy {
private Class classToIclude;
private Field[] declaredFields;
private List<FieldAttributes> fields;
public CustomIclusionStrategy(List<FieldAttributes> fields) {
this.fields = fields;
}
public CustomIclusionStrategy(Class classToIclude) {
this.classToIclude = classToIclude;
this.declaredFields=classToIclude.getDeclaredFields();
}
// called only if shouldSkipClass returns false
#Override
public boolean shouldSkipField(FieldAttributes f) {
try {
classToIclude.getSuperclass().getDeclaredField(f.getName());
System.out.println(f.getName());
return true;
} catch (Exception e) {
}
return false;
}
#Override
public boolean shouldSkipClass(Class<?> clazz) {
// if returns false shouldSkipField will be called, otherwise
//shouldSkipField will not be called
return false;
}
}
and call from here:
import java.util.ArrayList;
import java.util.List;
public class Node {
String id;
String name;
String data;
List<Node> children;
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 getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public List<Node> getChildren() {
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
public String toJson()
{
return JsonConvertor.toJson(this);
}
public Node(String id, String name, String data) {
super();
this.id = id;
this.name = name;
this.data = data;
}
public Node(String id, String name, String data, List<Node> children) {
super();
this.id = id;
this.name = name;
this.data = data;
this.children = children;
}
public static void main(String[] args) {
Node n5=new Node("1","YEAR-01","");
List<Node> list3=new ArrayList<Node>();
list3.add(n5);
Node n3=new Node("1","COMPUTER SCIENCE","",list3);
Node n4=new Node("1","EXTC","",list3);
List<Node> list=new ArrayList<Node>();
List<Node> list2=new ArrayList<Node>();
list2.add(n3);
list2.add(n4);
Node n2=new Node("1","STREAM-ENGG","",list2);
list.add(n2);
Node n1=new Node("1","EDUCATION","",list);
System.out.println(n1.toJson());
}
}
this is your json generated
{
"id": "1",
"name": "EDUCATION",
"data": "",
"children": [{
"id": "1",
"name": "STREAM-ENGG",
"data": "",
"children": [{
"id": "1",
"name": "COMPUTER SCIENCE",
"data": "",
"children": [{
"id": "1",
"name": "YEAR-01",
"data": ""
}]
},
{
"id": "1",
"name": "EXTC",
"data": "",
"children": [{
"id": "1",
"name": "YEAR-01",
"data": ""
}]
}]
}]
}
Here is way to convert Java Object to json
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new File("c:\\EducationDTO.json"), EducationDTO);
ArrayList is also a Java Object,even though java Object have iterative Objects it will convert it to JSON.
Suppose if you have recursive object like
class A { A a; //setters and getters }
Use JsonIdentityInfo in model class to break circular loops.
or go with
Use Jackson-Jsog plugin and annotate each class using below annotation.
#JsonIdentityInfo(generator=JSOGGenerator.class)

Categories

Resources