Unable to map API response to pojo - java

I have a json response
"data": {
"students": [
{
"id": 100,
"name": "ABC"
},
{
"id": 101,
"name": "XYZ"
}
I need to map it to my pojo, something like -
public class TempClass {
List<Temp> list_students;
}
class Temp {
Long id;
String name;
}
Direct reading API response into my pojo gives me a class cast exception. I've tried converting response to a list of map and the collect as Temp class but that also doesn't work.
Exception -
java.util.LinkedHashMap cannot be cast to java object
Any suggestions please?
Code snippet for conversion -
new TempClass(((LinkedHashMap<String, Object>) response.getData()).entrySet())
.stream().map(map -> mapper.convertValue(map, Temp.class))
.collect(Collectors.toList()))

public class Data{
public ArrayList<Student> students;
}
public class Root{
public Data data;
}
public class Student{
public int id;
public String name;
}
Your POJO class will look like this

Related

How to convert similar looking JSON structure into different POJO with Gson?

I am having below 2 JSON, one for login and another one for order
{
"head": {
"requestCode": "code"
},
"body": {
"reqId": "xyz",
"userName": "xyz",
"passwd": "xyz",
}
}
{
"head": {
"requestCode": "code"
},
"body": {
"reqId": "xyz",
"orderId": "xyz"
}
}
I am trying to write java pojo where the head and refId of body are common for each json but other content of body.
something like the below pojo. Now problem is GSon cannot parse and build objects based on nested parameterized types. Is there any better way to implement it? Not JSON structure will not change.
POJO
public class Base<T extends Body> {
#SerializedName("head")
#Expose
public Head head;
#SerializedName("body")
#Expose
private T body;
}
public class Body {
#SerializedName("clientCode")
#Expose
private String clientCode;
}
public class Head {
#SerializedName("requestCode")
#Expose
public String requestCode;
}
public class Login extends Body {
#SerializedName("userName")
#Expose
public String userName;
#SerializedName("passwd")
#Expose
public String passed;
}
public class Order extends Body {
#SerializedName("orderId")
#Expose
String orderId;
}
You could either introduce two new subclasses of Base which you use for deserialization, for example:
class LoginRequest extends Base<Login> { }
class OrderRequest extends Base<Order> { }
Or you can use Gson's TypeToken class to deserialize a parameterized Base type. See also the corresponding section in the user guide. For example:
Type loginType = new TypeToken<Base<Login>>() {}.getType();
Base<Login> loginRequest = gson.fromJson(..., loginType);

Problem with model in Java for given JSON

I need to create a model in Java to deseralize such JSON.
[
{
"yyy": {
"address": "y-a",
"acronym": "YYY"
},
"xxx": {
"address": "x-a",
"acronym": "XXX"
}
},
{
"vvv": {
"address": "v-a",
"acronym": "VVV"
}
}
]
It looks for me that a model in Java will look like here (i'm using Jackson)
public class Yyy{
public String address;
public String acronym;
}
public class Xxx{
public String address;
public String acronym;
}
public class Vvv{
public String address;
public String acronym;
}
public class Root{
public Yyy yyy;
public Xxx xxx;
public Vvv vvv;
}
It is not acceptable at all because I don't know which keys like xxx, yyy, vvv I will get -
They are not defined and can be random. What I need to do to convert this JSON to have something usefull? I mean to have an array of objects and in inside object a map where keys will be created from keys in JSON (vvv, yyy, xxx)

JSON parse using Gson giving null

I am trying to parse a JSON response documents using Gson but after parse it's giving me a null value
My JSON response is a Array of Documents
Java Code
//Code to convert the response into JSON
String res = gson.toJson(results);
//Parse the JSON
java.lang.reflect.Type collectionType = new TypeToken<List<Objects.JsonResponse>>() {}.getType();
List<Objects.JsonResponse> resp = gson.fromJson(res, collectionType);
System.out.println(resp.get(2).getName());
JAVA Object
package Objects;
import java.util.List;
import com.google.gson.annotations.SerializedName;
public class JsonResponse {
#SerializedName("product_id")
public static String product_id; //17
#SerializedName("create_date")
public static String create_date; //45
#SerializedName("image_small")
public static String image_small; //85
#SerializedName("image_large")
public static String image_large; //133
#SerializedName("name")
private static String name; //174
#SerializedName("description")
public static String description; //266
#SerializedName("tagline")
public static List<String> tagline;
#SerializedName("category")
public static List<String> category;
#SerializedName("catlevel0")
public static List<String> catlevel0;
#SerializedName("catlevel1")
public static List<String> catlevel1;
#SerializedName("catlevel2")
public static List<String> catlevel2;
#SerializedName("color")
public static List<String> color;
#SerializedName("size")
public static List<String> size;
#SerializedName("_version_")
public static String _version_;
#SerializedName("product_id")
public static String getName() {
return name;
}
public static void setName(String name) {
JsonResponse.name = name;
}
}
JSON document to be parsed is:
[
{
"product_id": "prod3400008",
"create_date": "2011-02-17T00:00:00Z",
"image_small": "/hul_images/small/17_Rexona.jpg",
"image_large": "/hul_images/large/17_Rexona.jpg",
"name": "Small Shell Cluster Loop Earrings",
"description": "Small Shell Cluster Loop Earrings",
"tagline": [
"B1G1 75% Off Jewelry "
],
"category": [
"Earrings"
],
"catlevel0": [
"Accessories"
],
"catlevel1": [
"Jewelry"
],
"catlevel2": [
"Earrings"
],
"color": [
"Clearly Coral",
"Mocha Brown",
"Blue Lagoon",
"Hunter Green",
"Medium Purple"
],
"_version_": 1527034576315089000
}
]
This is not a solutions, more like a tip. I found out the problem in your question. The problem is with the json array. If you remove all the arrays and just an object, this problem wont come. I dont know if you are aware of that already.
Please try the following json
{
"product_id": "prod3400008",
"create_date": "2011-02-17T00:00:00Z",
"image_small": "/hul_images/small/17_Rexona.jpg",
"image_large": "/hul_images/large/17_Rexona.jpg",
"name": "Small Shell Cluster Loop Earrings",
"description": "Small Shell Cluster Loop Earrings",
"_version_": 1527034576315089000
}
I removed all the arrays.
I have also removed the static declaration of your class JsonResponse, and static declaration of all your member variables.
And this is try this code:
Gson gson = new Gson();
String res = gson.toJson(results);
JsonResponse response = gson.fromJson(results, JsonResponse.class);
System.out.println(response.product_id);
System.out.println(response.create_date);
Hope this will help to figure out the problem. If you still cant find out, let me know... I will try harder... :-)
Object attributes are static and you should tell the GsonBuilder to serialize it.
follow this stack for more information.
Better practice would be not to make pojo class filed as static :)
Maybe it's giving you null because you messed up your annotations...
Also, remove static from all the methods and fields, you are trying to make instance variables, not class variables.
#SerializedName("product_id") // <---- not right
public String getName() { // <--- removed "static"
return name;
}

Jackson maps objects in [ ] but not in { }

I have a rest application and I'm using Jackson to convert objects to Jsons, but I have a problem:
public class Stats {
public int id;
public String name;
public int stat1;
public float stat2;
}
This method produces a following json:
[[8769,"TEST_PRODUCT#2#0",327,8.0],[8809,"TEST_PRODUCT#4#0",345,9.0],[8749,"TEST_PRODUCT#1#0",349,9.0],[8729,"TEST_PRODUCT#0#0",418,10.0],[8789,"TEST_PRODUCT#3#0",430,11.0]]
But [ and ] is start_array and end_array tokens, and so it is not correct as I think, because my objects are not arrays, so I think something like this would be correct:
[{id: 8769,name:"TEST_PRODUCT#2#0",stat1: 327,stat2: 8.0}, ......]
How can I map my List like this?

What is the data structure of this JSON?

I'm trying to parse Json to Java by using Gson, but when I use fromJson(), I always get null. Who can explain this data structure for me? Thanks!
{
"d": {
"results": [
{
"__metadata": {
"uri": "https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/v1/Web?Query='bill'gates'&$skip=0&$top=1",
"type": "WebResult"
},
"ID": "9bd0942f-fe5b-44fc-8343-ef85e5b93a7e",
"Title": "The Official Site of Bill Gates - The Gates Notes",
"Description": "In the space between business and goverment, even a small investment can make a big impact on the lives of those in need.",
"DisplayUrl": "www.thegatesnotes.com",
"Url": "http://www.thegatesnotes.com/"
},
{
"__metadata": {
"uri": "https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/v1/Web?Query='bill'gates'&$skip=1&$top=1",
"type": "WebResult"
},
"ID": "fdf0d3b9-b29f-43ef-b5ba-6bb4b1b04458",
"Title": "Bill Gates - Wikipedia, the free encyclopedia",
"Description": "William Henry \"Bill\" Gates III (born October 28, 1955) is an American business magnate and philanthropist. Gates is the former chief executive and current chairman of ...",
"DisplayUrl": "en.wikipedia.org/wiki/Bill_Gates",
"Url": "http://en.wikipedia.org/wiki/Bill_Gates"
}
],
"__next": "https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/v1/Web?Query='bill'gates'&$skip=10&$top=10"
}
}
I think the data structure should be like this, but it doesn't work.
public class d {
public result[] results;
public String __next;}
public class result {
public information[] infolist;}
public class information {
public __metadata metadata;
public String ID;
public String Title;
public String Description;
public String DisplayUrl;
public String Url;}
public class __metadata {
public String uri;
public String type;}
Your Information class is the problem. Put the Information stuff into Result and remove the infolist from Result. Also, the field name for the meta data is __metadata. This isn't the class name. Lastly, you're missing a class to wrap d as a field.
public class DataContainer {
public Data d;
}
public class Data {
public Result[] results;
public String __next;
}
public class Result {
public Metadata __metadata;
public String ID;
public String Title;
public String Description;
public String DisplayUrl;
public String Url;
}
public class Metadata {
public String uri;
public String type;
}
You really should use common convention for class names. Gson won't preclude you from using your own names for classes. It only requires control for the name of the fields.
To deserialize:
String json = ... ;
DataContainer myDataContainer = new Gson().fromJson(JSONString , DataContainer.class);
Result[] myResult = myDataContainer.d.results;
Try that and see if that works.
Here's how you should interpret the JSON when you're writing a class structure around it for Gson:
An opening { indicates an object, so this will be a new class (or an existing one if they have the same fields)
A "this": indicates a field for the object it's inside, and the field must be named the same thing as the text in the string.
An opening [ indicates an array, a List, or a Set (Result[] results could just as easily be List<Result> results)

Categories

Resources