Deserializing a structure of classes into a list - json

I'm kinda new to JSON but managed to handle the concept for quite a while on # until I stumbled on this problem.
In the background, I receive a JSON string that I cannot change and of which I do not have the class definition. So I have to mimic them to deserialize first.
Basically, most of the time, I deserialize lists like
"table" : [
{object},
{object}
]
And I'm fine.
Though
I found this architecture in a corner of the string I receive:
"list" : {
"item1":{object},
"item2":{object},
"item2":{object},
...
}
And as this list is pretty big, I'm quite annoyed to have to reproduce the structure into a rigid class like:
public class itemClass
{}
public class list
{
public ItemClass item1;
public ItemClass item2;
public ItemClass item3;
...
}
My question is : Is there a way to interpret all the items as a list instead and use the tag they have in front as the value of an attribute ?
So basically, can I serialize an attribute so that it becomes the title of the seralized item and backwards ?
I could automatize and my life would get easier.
is there anything like:
public class ItemClass
{
[magic JSON attribute that transforms this attribute's value into the title of the serialized string]
public string title;
public int otherValues;
}
public class list
{
public List<ItemClass> items;
}
I hope you have some ideas to share.
Thanks

Related

Angular casting http get response but not nested property

I am returning a list of products of type ListProd in my Spring Boot controller, and such object has a nested property of type List<Product> ... something like this:
public class Product implements Serializable {
int codProdct;
String dsc;
public Product(){};
// plus getters and setters (omitted for simplicity)
}
public class ListProd implements Serializable {
int codList;
List<Product> products;
public ListProd(){};
// also here getters and setters
}
and in my angular project I have the next analogoust entities:
export class Product {
public codProduct:number;
public dsc:string;
constructor(){
codProduct=null; //just for completness
dsc='';
}
}
export class ListProd {
public codList:number;
public products:Product[];
constructor(){
this.codList=null; //just for completness
this.products=null;
}
}
I'm sending a ListProd object through my Spring controller and Angular gets such an object correctly and assigns the type also correctly:
return this.http.get<ListProd>(this.apiUrl + "/getListProds", httpOptions);
but ... it is only casting correctly the parent object, when I check the type of the 'products' object (which is recived correctly, only untyped) y get type: Object
I tried to make it a Products[] in my ListProd class in java, but i get the same result. I don't know much about the 'magic' Angular does to assign those types properly, am I missing something important here? Is there a chance to force the casting on the Angular side?
Thanks in advance.
Well, if ListProd is supposed to hold array of Product[] there is a typo here.
public products:Product[];
Not knowing full extent why you use class over an interface I would advise you also to go over this. Maybe there is a reason but for being able to strong type simple interface would be better. https://www.javatpoint.com/typescript-class-vs-interface

GSON not reading values correctly

I'm trying to read this JSON:
And I can't seem to get it to work with GSON. I've used GSON successfully in the same project so I know how it works but I can't seem to get this JSON to work as intended. First in the class is rows, which is just an array of another class. The other class has three variables, a string named "code", a string named "name", and a array of another class called "statuses". However, I don't know how to put variables in this other class. It looks like an array but it's not. I cannot name a variable "0" in Java, so I looked that up (tried fixing it with Maps) but that did not work. How would you do this? It's weird because "statuses" always contains just that one entry, named '0', and the text is either "primary" or "secondary". Any help is appreciated.
I actually found this:
Still not really sure how to go about this.
Your Pojo design shoild be like this :-
public class ResultOutPut {
private List<Rows> rows;
// getters and setters
}
public class Rows {
private String code;
private String name;
private List<String> statuses;
// getters and setters
}

Handle java inheritance in json

My class is as below:
class A
{
private B b;
private String id;
//setter and getter
}
class B
{
private String name;
//setter and getter
}
class C extends B
{
private String email;
//setter and getter
}
My Json is as below:
{
"name":"Sample",
"id":2,
"email":"support#abd.com"
}
Now when I try to deserialise my json into a java object, I get:
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "email"
Please let me know how I could solve this.
You need to make sure that you are handling deserializing the shared nodes in the base class, and the nodes specific to your class b/c in their own respective classes. If you are handling deserialization in your top level class, it won't recognize a unique property in an inheriting class.
It's difficult to see where you are going wrong without seeing your individual classes.

Jackson Serialize and Deserialize String property as JSON

I have a model that looks like this (Play 2.1.1 java ebean)
#Entity
public class Link extends Model {
#Id
public Long id;
#Lob
public String points;
}
where points is a raw json string that contains x, y coordinates in an array.
I don't want to have to deserialize it to an array of Points, because it's only going to be used for the UI. and thus, I would like to save it to a text field in the database
I want the property points to get serialized as a json array when sent over the wire to the frontend and I want the frontend to be able to send an json array and make it into a string again.
In the controller:
// Serialize
List<Link> links = Link.findAll();
return ok(Json.toJson(links));
// Deserialize
Link link = Json.fromJson(request().body().asJson(), Link.class);
How should I do this?
Custom serializer, deserializer?
#JsonRawValue?
Any other annotation?
The answer was a lot simpler than you would suspect.
#Lob
public String points;
public JsonNode getPoints() {
return Json.parse(StringUtils.isBlank(points) ? "[]" : points);
}
#JsonSetter
public void setPoints(JsonNode json) {
points = json.toString();
}
Though I'm not that fond of getter's and setter's it works.
If anyone has a better solution that is more generic, feel free to post another answer :)

Jackson deserialization when POJO does not match JSON structure

I have some json :
{
key: "CORE-19",
fields: { summary: "iblah" }
}
I want to pack it into a POJO that looks more like:
#JsonIgnoreProperties(ignoreUnknown=true)
public class JiraIssue
{
private String mKey;
private String mSummary;
public String getKey(){ return(mKey);}
public void setKey(String inKey){mKey = inKey;}
public String getSummary(){return(mSummary);}
public void setSummary(String summary){ mSummary = summary; }
}
So basically I don't want to create a 'Fields' object as it is a bit superfluous for my needs. However I really can't see any way in Jackson to tell it that the 'summary' property actually comes from the 'fields' property. Is this possible?
Serialization of this class is not a concern, it will only ever be used for Deserialization. I have no control over the JSON format as it is coming from an external source (and the above is just a snippet). Also I'm actually using Jackson with Jersey.
Thanks!
There is actually an open issue for this kind of structural change. There is no way as of now to do that easily with annotation only without modifying your class. What you could do instead is handle the "fields" property as a "false" property, by adding the following method:
public void setFields(Map<String, String> fields) {
setSummary(fields.get("summary"));
}
This way you "unwrap" the property yourself.
Try:
#JsonProperty("fields.summary")
private String mSummary;