This is one in a row of deserialization questions but I've read them all and can't figure out the solution for my problem.
I need to get all the "entery"->"content" ->$t and "entery"->"title"->"$t" but in CategoryDeserializer() I get JsonArray that is NULL. I've pointed to that part of the code with "<====".
Error message:
Attempt to invoke interface method 'java.util.Iterator
java.util.List.iterator()' on a null object reference
I have JSON that looks something like this:
{ "feed":{
"id":{ ... },
"author":[ ... ],
"entry":[
{
"id":{ },
"updated":{ },
"category":[ ],
"title":{
"type":"text",
"$t":"A1 },
"content":{
"type":"text",
"$t":"test"
},
"link":[ ]
},
{ ... },
{ ... },
{ ...},
]
}
}
This is part of my code where I try to deserialize "entery":
String json = response.body().toString();
Type listType = new TypeToken<List<Entry>>() {
}.getType();
Gson gson = new GsonBuilder().registerTypeAdapter(listType, new CategoryDeserializer()).create();
List<Entry> list = gson.fromJson(json, listType);
for (Entry entry : list) {
Log.i("MainActivity", "Content: " + entry.getContent());}
Where CategoryDeserializer() looks like this:
public class CategoryDeserializer implements JsonDeserializer<List<Entry>> {
public List<Entry> deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
JsonArray entry = je.getAsJsonObject().getAsJsonArray("entry"); //<==== here I get that entry is null but je has a value
ArrayList<Entry> myList = new ArrayList<Entry>();
for (JsonElement e : entry) {
myList.add((Entry) jdc.deserialize(e, Entry.class));
}
return myList;}
And my Entry class:
public class Entry {
private Id_ id;
private Updated_ updated;
private List<Category_> category = null;
private Title_ title;
private Content content;
private List<Link_> link = null;
//getters and setters
public Id_ getId() {
return id;
}
public void setId(Id_ id) {
this.id = id;
}
public Updated_ getUpdated() {
return updated;
}
public void setUpdated(Updated_ updated) {
this.updated = updated;
}
public List<Category_> getCategory() {
return category;
}
public void setCategory(List<Category_> category) {
this.category = category;
}
public Title_ getTitle() {
return title;
}
public void setTitle(Title_ title) {
this.title = title;
}
public Content getContent() {
return content;
}
public void setContent(Content content) {
this.content = content;
}
public List<Link_> getLink() {
return link;
}
public void setLink(List<Link_> link) {
this.link = link;
}
}
Edit: I have declaration and instantiation.
I was complicating things that were not complicated. All I had to do was this:
String json = response.body().toString();
Gson mGson = new Gson();
//where Example is the root of JSON
Example rsp = mGson.fromJson(json, Example.class);
//Entry is the list I needed to access
List <Entry> listOfEntrys= rsp.getFeed().getEntry();
//get value
Log.i("MainActivity", "listaEntrya " + listOfEntrys.get(0).getTitle().get$t());
Related
Below is my JSON data. I want to convert this to POJOs to store the Name,id,profession in a header table and the respective Jsonarray field in a child table.
JSON:
{
"Name": "Bob",
"id": 453345,
"Profession": "Clerk",
"Orders": [
{
"Item": "Milk",
"Qty": 3
},
{
"Item": "Bread",
"Qty": 3
}
]
}
Entity classes:
public class User {
private String name;
private Integer id;
private String Profession;
private JsonArray Orders;
private UserCart userCart;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProfession() {
return Profession;
}
public void setProfession(String profession) {
Profession = profession;
}
public JsonArray getOrders() {
return Orders;
}
public void setOrders(JsonArray orders) {
Orders = orders;
}
public UserCart getUserCart() {
return userCart;
}
public void setUserCart(UserCart userCart) {
this.userCart = userCart;
}
}
public class UserCart {
private String item;
private Integer qty;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public Integer getQty() {
return qty;
}
public void setQty(Integer qty) {
this.qty = qty;
}
}
But when I do below; I get error
Cannot deserialize instance of org.json.JSONArray out of START_ARRAY
token
User user = new User();
JsonNode data = new ObjectMapper().readTree(jsonString);
user = headerMap.readValue(data.toString(), User.class);
How do I go about assigning the entire JSON to both the Java objects ?
Use List<UserCart> for array data in json and use #JsonProperty for mapping different json node name to java object field. No need to use extra field (JsonArray Orders) anymore.
#JsonProperty("Orders")
private List<UserCart> userCart;
I have json like:
{"avatars": {
"1": "value",
"2":"value",
"900":"value"
}
}
And my model:
class Response{
List<Avatar> avatars;
}
class Avatar{
String id;
String value;
}
How do I properly parse the Json using Jackson
You should use json like this to automaticaly parse:
{"avatars": [
{"id": "1", "value": "someValue1"},
{"id": "2", "value": "someValue2"},
{"id": "300", "value": "someValue300"},
]
}
or write custom parser for Jackson.
Try this:
Using Java JSON library
public class Test {
public static void main(String[] args) {
Response response = new Response();
Serializer.serialize("{\"avatars\": { \"1\": \"value\", \"2\":\"value\", \"900\":\"value\" }}", response);
System.out.println(response.toString());
}
}
class Serializer {
public static void serialize(String j, Response response) {
try {
JSONObject json = new JSONObject(j).getJSONObject("avatars");
Iterator keys = json.keys();
while (keys.hasNext()) {
String id = keys.next().toString();
String value = json.getString(id);
response.addAvatar(id, value);
}
} catch (JSONException ignore) {
}
}
}
/**
* This is a response class
*/
class Response {
List<Avatar> avatars;
public Response() {
/**
* You can use LinkedList, I think it's the best way.
*/
this.avatars = new LinkedList<Avatar>();
}
public void addAvatar(String id, String value) {
this.avatars.add(new Avatar(id, value));
}
public String toString() {
String result = "";
for (Avatar avatar : this.avatars) {
result += (result.length() == 0 ? "" : ", ") + "[" + avatar.getId() + "=" + avatar.getValue() + "]";
}
return result;
}
}
/**
* This is an avatar class
*/
class Avatar {
private String id;
private String value;
public Avatar(String id, String value) {
this.id = id;
this.value = value;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Hope this helps!
You can just use a converter, which avoids the complexity of a full custom deserializer:
#JsonDeserialize(converter = AvatarMapConverter.class)
public List<Avatar> avatars;
The converter needs to declare that it can accept some other type that Jackson can deserialize to, and produce a List<Avatar>. Extending StdConverter will do the plumbing for you:
public class AvatarMapConverter extends StdConverter<Map<String, String>, List<Avatar>> {
#Override
public List<Avatar> convert(Map<String, String> input) {
List<Avatar> output = new ArrayList<>(input.size());
input.forEach((id, value) -> output.add(new Avatar(id, value)));
return output;
}
}
If you need to serialize too, you can write a converter to go the other way and reference that from a #JsonSerialize annotation.
I'm trying deserializes a JSONArray to List. To do it I'm trying use Gson but I can't understand why doesn't works and all values of JSON are null.
How could I do this ?
JSON
{ "result" : [
{ "Noticia" : {
"created" : "2015-08-20 19:58:49",
"descricao" : "tttttt",
"id" : "19",
"image" : null,
"titulo" : "ddddd",
"usuario" : "FERNANDO PAIVA"
} },
{ "Noticia" : {
"created" : "2015-08-20 19:59:57",
"descricao" : "hhhhhhhh",
"id" : "20",
"image" : "logo.png",
"titulo" : "TITULO DA NOTICIA",
"usuario" : "FERNANDO PAIVA"
} }
] }
Deserializes
List<Noticia> lista = new ArrayList<Noticia>();
Gson gson = new Gson();
JSONArray array = obj.getJSONArray("result");
Type listType = new TypeToken<List<Noticia>>() {}.getType();
lista = gson.fromJson(array.toString(), listType);
//testing - size = 2 but value Titulo is null
Log.i("LISTSIZE->", lista.size() +"");
for(Noticia n:lista){
Log.i("TITULO", n.getTitulo());
}
Class Noticia
public class Noticia implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String titulo;
private String descricao;
private String usuario;
private Date created;
private String image;
There are two problems with your code :
First is that you are using a getJsonArray() to get the array,
which isn't part of Gson library, you need to use
getAsJsonArray() method instead.
Second is that you are using array.toString() which isn't obvious
because for the fromJson method you need a jsonArray as
parameter and not String and that will cause you parse problems, just remove it.
And use the following code to convert your jsonArray to List<Noticia> :
Type type = new TypeToken<List<Noticia>>() {}.getType();
List<Noticia> lista = gson.fromJson(array, type);
And your whole code will be:
Gson gson = new Gson();
JSONArray array = obj.getAsJsonArray("result");
Type type = new TypeToken<List<Noticia>>() {}.getType();
List<Noticia> lista = gson.fromJson(array, type);
//testing - size = 2 but value Titulo is null
Log.i("LISTSIZE->", lista.size() +"");
for(Noticia n:lista){
Log.i("TITULO", n.getTitulo());
}
I think the problem could be something to do with toString() on JSONArray. But are you using obj.getAsJsonArray method?
Try this:
JSONArray arr = obj.getAsJsonArray("result");
Type listType = new TypeToken<List<Noticia>>() {
}.getType();
return new Gson().fromJson(arr , listType);
Noticia.java
public class Noticia {
private String created;
private String descricao;
private String id;
private String image;
private String titulo;
private String usuario;
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getUsuario() {
return usuario;
}
public void setUsuario(String usuario) {
this.usuario = usuario;
}
#Override
public String toString() {
return "Noticia [created=" + created + ", descricao=" + descricao
+ ", id=" + id + ", image=" + image + ", titulo=" + titulo
+ ", usuario=" + usuario + "]";
}
}
Result.java
public class Result {
private Noticia Noticia;
public Noticia getNoticia() {
return Noticia;
}
public void setNoticia(Noticia noticia) {
Noticia = noticia;
}
#Override
public String toString() {
return "Result [Noticia=" + Noticia + "]";
}
}
Item.java
import java.util.List;
public class Item {
private List<Result> result;
public List<Result> getResult() {
return result;
}
public void setResult(List<Result> result) {
this.result = result;
}
#Override
public String toString() {
return "Item [result=" + result + "]";
}
}
Main.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.testgson.beans.Item;
public class Main {
private static Gson gson;
static {
gson = new GsonBuilder().create();
}
public static void main(String[] args) {
String j = "{\"result\":[{\"Noticia\":{\"created\":\"2015-08-20 19:58:49\",\"descricao\":\"tttttt\",\"id\":\"19\",\"image\":null,\"titulo\":\"ddddd\",\"usuario\":\"FERNANDO PAIVA\"}},{\"Noticia\":{\"created\":\"2015-08-20 19:59:57\",\"descricao\":\"hhhhhhhh\",\"id\":\"20\",\"image\":\"logo.png\",\"titulo\":\"TITULO DA NOTICIA\",\"usuario\":\"FERNANDO PAIVA\"}}]}";
Item r = gson.fromJson(j, Item.class);
System.out.println(r);
}
}
Final result
Item [result=[Result [Noticia=Noticia [created=2015-08-20 19:58:49, descricao=tttttt, id=19, image=null, titulo=ddddd, usuario=FERNANDO PAIVA]], Result [Noticia=Noticia [created=2015-08-20 19:59:57, descricao=hhhhhhhh, id=20, image=logo.png, titulo=TITULO DA NOTICIA, usuario=FERNANDO PAIVA]]]]
You parse json, that looks like
{ "result" : [
{
"created" : "2015-08-20 19:58:49",
"descricao" : "tttttt",
"id" : "19",
"image" : null,
"titulo" : "ddddd",
"usuario" : "FERNANDO PAIVA"
},
{
"created" : "2015-08-20 19:59:57",
"descricao" : "hhhhhhhh",
"id" : "20",
"image" : "logo.png",
"titulo" : "TITULO DA NOTICIA",
"usuario" : "FERNANDO PAIVA"
}
] }
You need to make another object Item and parse a list of them.
public class Item{
Noticia noticia;
}
Or you can interate through JSONArray, get field "noticia" from each then parse Noticia object from given JSONObject.
Kotlin Ex :
we getting response in form of JSONArry
call.enqueue(object : Callback<JsonArray> {
override fun onResponse(call: Call<JsonArray>, response: Response<JsonArray>) {
val list = response.body().toString()
val gson = Gson()
val obj: CitiesList? = gson.fromJson(list, CitiesList::class.java)
cityLiveData.value = obj!!
}
override fun onFailure(call: Call<JsonArray>, t: Throwable) {
}
})
Here CitiesList CitiesList::class.java is the ArrayList of Cities object
class CitiesList : ArrayList<CitiesListItem>()
Before using GSON add dependancey in Gradle
dependencies {
implementation 'com.google.code.gson:gson:2.8.8'
}
I have to generate JSON in below sample format:
[
{ "roleName" : "Parent Folder", "folderId" : "role1", "expanded" : true,
"children" :
[
{ "roleName" : "subUser1 non-openable folder", "folderId" : "role11","fileicon" : true },
{ "roleName" : "subUser2", "folderId" : "role12", "expanded" : true,
"children" :
[
{ "roleName" : "subUser2-1", "folderId" : "role121", "expanded" : true, "children" :
[
{ "roleName" : "subUser2-1-1 folder ico", "folderId" : "role1211" },
{ "roleName" : "subUser2-1-2 file ico", "folderId" : "role1212" , "fileicon" : true}
]
}
]
}
]
}
]
I have created POJO for same and was able to add array elements in, but unable to add one more array inside or below the element. Please suggest.
below are the pojo I am using.
public class TargetFolder
{
private TargetChildren[] children;
private String roleName;
private String expanded;
private Long folderId;
public TargetFolder(String roleName,
String isFolder, Long folderId, TargetChildren[] folderList) {
super();
this.roleName = roleName;
this.expanded = isFolder;
this.folderId = folderId;
this.children = folderList;
}
public TargetChildren[] getChildren ()
{
return children;
}
public void setChildren (TargetChildren[] children)
{
this.children = children;
}
public String getRoleName ()
{
return roleName;
}
public void setRoleName (String roleName)
{
this.roleName = roleName;
}
public String getExpanded ()
{
return expanded;
}
public void setExpanded (String expanded)
{
this.expanded = expanded;
}
public Long getFolderId ()
{
return folderId;
}
public void setFolderId (Long folderId)
{
this.folderId = folderId;
}
#Override
public String toString()
{
return "ClassPojo [children = "+children+", roleName = "+roleName+", expanded = "+expanded+", folderId = "+folderId+"]";
}
}
and
public class TargetChildren
{
private String fileicon;
private String roleName;
private long folderId;
public TargetChildren(String roleName, String fileicon, long folderId) {
super();
this.fileicon = fileicon;
this.roleName = roleName;
this.folderId = folderId;
}
public String getFileicon ()
{
return fileicon;
}
public void setFileicon (String fileicon)
{
this.fileicon = fileicon;
}
public String getRoleName ()
{
return roleName;
}
public void setRoleName (String roleName)
{
this.roleName = roleName;
}
public long getFolderId ()
{
return folderId;
}
public void setFolderId (long folderId)
{
this.folderId = folderId;
}
#Override
public String toString()
{
return "ClassPojo [fileicon = "+fileicon+", roleName = "+roleName+", folderId = "+folderId+"]";
}
}
and below is the logic I am using to generate the JSON:
for(int i = 0; i<folderList.size();i++)
{
if(folderList!=null)
{
subList = (List)folderList.get(i);
childFolders[i] = new TargetChildren((String)subList.get(0),(String)subList.get(2),(Long)subList.get(1));
JSONArray arr = new JSONArray();
if(((String)subList.get(2)).equals("true"))
{
arr.put(i, childFolders[i]);
}
System.out.println(arr.toString());
//TargetChildren [] testArr = new TargetChildren[] { new TargetChildren("Folder", "folderName", 226886843L)};
}
}
TargetFolder targetFolder = new TargetFolder(parentFoldername,isFolder,folderId, childFolders);
JSONObject jsonObject = new JSONObject(targetFolder);
String jsonString = jsonObject.toString();
System.out.println("JSON TO UI------ "+jsonString);
The most elegant and simple solution I can think of is adding a toJSON method to your POJOs and let it handle the serializing itself.
For the TargetFolder:
public JSONObject toJSON(){
JSONObject out = new JSONObject();
out.put("rolename", rolename);
out.put("expanded", expanded);
out.put("folderID", folderId);
JSONArray children = new JSONArray();
for(int i = 0; i < this.children.length; i++){
children.push(this.children[i].toJSON());
}
out.put("children", children);
return out;
}
Do the same for the TargetChildren and then you can convert it to JSON by calling:
myTargetFolder.toJSON();
This way you don't need to worry about the recursive structure of the resulting JSON.
If you add a constructor which takes a JSONObject, you can ensure consistent serialization and deserialization in one place.
There is also the GSON library from Google, which should achieve essentially the same, but I never used it, so I cannot say how it would work with that.
P.S.: You might want to create a common superclass for TargetFolder and TargetChild and use that as the datatype for the children-array, because from the JSON it seems like this array can contain objects with TargetFolder-properties ("expanded" and "children") and objects with TargetChild-properties ("fileicon")
Given I have the following json:
{
"Company": {
"name": "cookieltd",
"type": "food",
"franchise_location": [
{
"location_type": "town",
"address_1": "5street"
},
{
"location_type": "village",
"address_1": "2road"
}
]
}
}
How can it be binded to the following object classes using Jackson?:
1) Company class
public class Company
{
String name, type;
List<Location> franchise_location = new ArrayList<Location>();
[getters and setters]
}
2) Location class
public class Location
{
String location_type, address_1;
[getters and setters]
}
I have done:
String content = [json above];
ObjectReader reader = mapper.reader(Company.class).withRootName("Company"); //read after the root name
Company company = reader.readValue(content);
but I am getting:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "franchise_location"
As far as I can tell, you are simply missing an appropriately named getter for the field franchise_location. It should be
public List<Location> getFranchise_location() {
return franchise_location;
}
(and the setter)
public void setFranchise_location(List<Location> franchise_location) {
this.franchise_location = franchise_location;
}
Alternatively, you can annotate your current getter or field with
#JsonProperty("franchise_location")
private List<Location> franchiseLocation = ...;
which helps to map JSON element names that don't really work with Java field name conventions.
The following works for me
public static void main(String[] args) throws Exception {
String json = "{ \"Company\": { \"name\": \"cookieltd\", \"type\": \"food\", \"franchise_location\": [ { \"location_type\": \"town\", \"address_1\": \"5street\" }, { \"location_type\": \"village\", \"address_1\": \"2road\" } ] } }";
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.reader(Company.class).withRootName(
"Company"); // read after the root name
Company company = reader.readValue(json);
System.out.println(company.getFranchise_location().get(0).getAddress_1());
}
public static class Company {
private String name;
private String type;
private List<Location> franchise_location = new ArrayList<Location>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Location> getFranchise_location() {
return franchise_location;
}
public void setFranchise_location(List<Location> franchise_location) {
this.franchise_location = franchise_location;
}
}
public static class Location {
private String location_type;
private String address_1;
public String getLocation_type() {
return location_type;
}
public void setLocation_type(String location_type) {
this.location_type = location_type;
}
public String getAddress_1() {
return address_1;
}
public void setAddress_1(String address_1) {
this.address_1 = address_1;
}
}
and prints
5street
my solution for JSON is always GSON, you can do some research on that, as long as you have the correct structure of class according to the JSON, it can automatically transfer from JSON to object:
Company company = gson.fromJson(json, Company.class);
GSON is so smart to do the convertion thing!
enjoy GSON !