Using Gson to parse Json array and object with no name - java

I know there are many JSON with GSON questions but none of them relate to me directly. My JSON is formatted differently.
I have a JSON data I want to parse using GSON which looks like the following:
[
{
"foo":"1",
"bar":[ { "_id":"bar1"} ],
"too":["mall", "park"]
}
]
And I have the model Classes:
ItemArray Class
public class ItemArray
{
List<Item> itemArray;
//Get set here
}
Item Class
public class Item
{
String foo;
List<Bar> bar;
List<String> too;
//Get set here
}
Bar Class
public class Bar
{
String id;
//Get set here
}
Heres the question. Is the JSON in the correct format? If so, are the model classes in the correct format?
If not, please shove me in the right direction. Thank you in advance!
PS. I can modify the JSON data format if need be.

According to your json, you should simply have :
public class ItemArray extends List<Item> {
}
if you want to keep you java class and change your json it should be :
{
itemArray: [
{
"foo":"1",
"bar":[ { "_id":"bar1"} ],
"too":["mall", "park"]
}
]
}
Oh, and there is a mismatch with the id and _id for Bar :
public class Bar
{
String _id;
//Get set here
}
You could also use an annotation to change the field's name during Json de/serialization.
And last but not least, consider typing your values better. Don't see any data as strings if they are not, you will not a lot of processing in java code to convert things. For instance :
"foo" : 1,
and see foo as an int data member, not a String.

Some times we get JsonArray [ {..} , {..} ] as a response (without 'itemArray' name like yours)
In that case you can use following code
Type fooType = new TypeToken<ArrayList<Item>>() {}.getType();
List<Item> array = new Gson().fromJson(response, fooType);
find more about this Official doc - Gson Array-Examples

If you have a JsonArray like [ {..} , {..} ] you can do this with Gson:
Item[] items = gson.fromJson(json, Item[].class);

To check Json is valid use this tool http://jsonlint.com/
Class Bar(
private String _id;
//create getter/setters
{
public class Item
{
String foo;
List<Bar> bar;
List<String> too;
//Get set here
}
//this is also fine
public class ItemList
{
List<Item> itemArray;
//Get set here
}
you named of list of items "itemArray", but in your json you have not named the corresponding array of items "itemArray".
So make it itemArray, The problem is not in your json, it is valid. Problem is in its representation for Gson,
Gson map keys of json on the variables of object (i.e Java POJO) with same name.
If the name of your list is Class is
List<Item> itemArray;
then the corresponding json array name should also be itemArray, take a look blow
{
itemArray: [
{
"foo":"1",
"bar":[ { "_id":"bar1"} ],
"too":["mall", "park"]
}
]
}
so you can convert json into object like that
Reader reader = new InputStreamReader(IOUtils.toInputStream(json_string));
ItemList itemList = json.toObject(reader, ItemList.class);
Take a look into blow reference for more details
https://stackoverflow.com/questions/13625206/how-to-parse-the-result-in-java/13625567#13625567

Related

Gson why does my deserialization not work?

I am trying to make a java program that will need to work with json, I have choose gson as my library to handle managing JSON
But when I try to deserialize my json the messagereturn.text value and the messagereturn.extra.text value both get set as null, I have tried to fix this but I am unable to.
An example of the json that i am trying to deserialize is
{
"text":"",
"extra":[{
"text":"eee joined the game",
"color":"yellow"
}]
}
And this is how I am calling gson
Message messagepacket = event.<ServerChatPacket>getPacket().getMessage();
//this gets the json data
messagereturn messagereturn = gson.fromJson(String.valueOf(messagepacket), messagereturn.class);
System.out.println(messagereturn.returnmethod());
Here is the class I am trying to deserialize too
public class messagereturn {
String text;
public class extra{
String text;
}
public String returnmethod() {
extra extra = new extra();
return text + extra.text;
}
}
Thank you, if there is any more informaton needed let me know, thanks
There is a problem understanding your JSON (and creating the Java classes by the way). These marks [] means that is a list.
So you have an object with atributes text, type String and extra, type List<Object>.
This list contains another object (note that the object is defined by {} and list by []).
The object into the list has another two attributes: text and color both with primitive types; String.
So your java class should be like this:
public class Messagereturn {
private String text;
private List<Extra> extra;
//getters and setters and other methods
}
And the class Extra:
public class Extra {
private String text;
private String color;
//getters and setters
}
With this data model you can call your Gson with these structure.
Also, you don't need to call returnMethod to create Extra object, it is created by Gson.
Using this line of code:
Messagereturn mr = new Gson().fromJson(txt, Messagereturn.class);
And your JSON example, this is the value stored when run in debug mode:
As you can see, tha values from JSON has been created and loaded into memory.

Deserialize JSON With Only Canonical Type String Using Jackson

I have a JSON string
{
"type": "com.example.model.Person",
"data": {
"firstName": "Bob",
...
}
}
That is represented by the following class.
public class Container<T> {
private String type;
private T data;
// Getters and Setters
}
(I've even tried just removing the generic type and replacing it with Object.)
I have tried the following:
new ObjectMapper().readValue(json, Class.forName(canonical))
new ObjectMapper().readValue(json, TypeFactory.defaultInstance().constructFromCanonical(canonical))
I need to be able to deserialize the JSON string into a Container<T> instance with only the given canonical type string. How can this be done?
I tried the same example and its working for me
Is it the same you are looking for or something else

Deep JSON structures to Java object, is there a better way than what I did? It looks horrendous

So I have this JSON structure I'm getting as a HTTP response. Structure looks like this:
{
"field1": "value1",
"field2": {
"field2-2": [
{
"field2-2-1": "some value",
"field2-2-2": {
"key" : "some value"
}
}
]
}
}
Of course I simplified it but you get the idea. Now I use Gson to convert it into a HashMap:
HashMap<String, Object> resultMap = new Gson().fromJson(httpResult, type);
Now, to get to the "field2-2-2" in Java I do this:
LinkedTreeMap someMap = (LinkedTreeMap) resultMap.get("field2");
ArrayList<LinkedTreeMap> someList = (ArrayList) someMap.get("field2-2");
LinkedTreeMap anotherMap = someList.get(0);
anotherMap.get("key");
Once again I simplified it, but is there any better way to access this "deep" field? Or for the sake of readability can I chain methods somehow? What I mean is if this all have been ArrayLists I could do something like:
ArrayList<Arraylist<String>> sampleList = new ArrayList<>();
sampleList.get(0).get(0);
You could directly map it to POJO classes. Like:
#JsonInclude(Include.NON_NULL)
public class ApiResponse {
String field01;
Field2Class field02;
}
Field2Class.class
public class Field2Class {
ArrayList<Field02_2> field02_2;
}
Field02_2.class
public class Field02_2 {
String field02_2_1, field02_2_2;
}
With each class having getters, setters and default constructors.

json jackson inner collection deserialize as LinkedHashMap instead of MyObject

I have the following object structure, on which I can't do any modification (this is a library and I don't have sources) :
class Foo {
List bars; // with no generics (but this is a List<Bar>)
Baz baz;
}
class Bar {
Fiz fiz;
Buz buz;
}
class Baz {
int toto;
}
class Fiz {
String titi;
}
class Buz {
String tata;
}
And the following json :
{
"bars" : [
{
"fiz" : {
"titi" : "Hello"
},
"buz" : {
"tata" : "World"
}
},
{
"fiz" : {
"titi" : "Hola"
},
"buz" : {
"tata" : "El Mundo"
}
}
],
"baz" : {
"toto" : 42
}
}
I try to deserialize the json with the following code :
ObjectMapper mapper = new ObjectMapper();
// ... use the visibilityChecker because objects are immutable (no setter)
mapper.readValue(json, Foo.class);
I retrieve a List of LinkedHashMap instead of a List of Bar. I've check all others posts on the subject on stackoverflow, but each time, the list is at the top level so it is quite easy. I tried to use mixin without success, i tried with enableDefaultTyping but i got an error...
How can i do this ? I repeat I cannot modify the class files, add annotations, add intermediary objects, ... everything is in a library.
EDIT 21/12/2016 :
I tried with Mixin :
abstract class FooMixin {
#JsonProperty("bars")
#JsonDeserialize(contentAs = Bar.class)
List bars;
}
abstract class BarMixin {
#JsonProperty("fiz") Fiz fiz;
#JsonProperty("buz") Buz buz;
}
mapper.addMixin(Foo.class, FooMixin.class);
mapper.addMixin(Bar.class, BarMixin.class);
But got the same result (LinkedHashMap)...
Even if you don't control library code, you can still use mix-in annotations:
http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html
which is the way to go. One possibility here is to "mix in":
#JsonDeserialize(contentAs=Bar.class)
to augment type information; this needs to be before List-valued field or setter-method used to assign it.

JSON - deserialization of dynamic object using Gson

Let's imagine I have a Java class of the type:
public class MyClass
{
public String par1;
public Object par2;
}
Then I have this:
String json = "{"par1":"val1","par2":{"subpar1":"subval1"}}";
Gson gson = new GsonBuilder.create();
MyClass mClass = gson.fromJson(json, MyClass.class);
The par2 JSON is given to me from some other application and I don't ever know what are it's parameter names, since they are dynamic.
My question is, what Class type should par2 variable on MyClass be set to, so that the JSON String variable is correctly deserialized to my class object?
Thanks
Check out Serializing and Deserializing Generic Types from GSON User Guide:
public class MyClass<T>
{
public String par1;
public T par2;
}
To deserialize it:
Type fooType = new TypeToken<Myclass<Foo>>() {}.getType();
gson.fromJson(json, fooType);
Hope this help.
See the answer from Kevin Dolan on this SO question: How can I convert JSON to a HashMap using Gson?
Note, it isn't the accepted answer and you'll probably have to modify it a bit. But it's pretty awesome.
Alternatively, ditch the type safety of your top-level object and just use hashmaps and arrays all the way down. Less modification to Dolan's code that way.
if you object has dynamic name inside lets say this one:
{
"Includes": {
"Products": {
"blablabla": {
"CategoryId": "this is category id",
"Description": "this is description",
...
}
you can serialize it with:
MyFunnyObject data = new Gson().fromJson(jsonString, MyFunnyObject.class);
#Getter
#Setter
class MyFunnyObject {
Includes Includes;
class Includes {
Map<String, Products> Products;
class Products {
String CategoryId;
String Description;
}
}
}
later you can access it:
data.getIncludes().get("blablabla").getCategoryId()
this code:
Gson gson = new GsonBuilder.create();
should be:
Gson gson=new Gson()
i think(if you are parsing a json doc).

Categories

Resources