Converting JSONArray to List<Object>? - java

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'
}

Related

Using Jackson to produce desired JSON response

Could anyone tell me what am I doing wrong while printing the JSON using Jackson. Here's my controller code :
#RequestMapping(value="/get_employee_details", method=RequestMethod.GET)
public String updateemployee
(
#RequestParam(value="emp_id", defaultValue="0") Integer emp_id,
#RequestParam(value="name", defaultValue="") String name
)
{
String responseJSON = null;
boolean getStatus = true;
try {
EmployeeDao employeeDao = (EmployeeDao)context.getBean("employeeDao");
Employee employee = null;
List<Employee> empList = employeeDao.findByEmployeeId(emp_id);
if ((empList != null) && (!empList.isEmpty())) {
List<String> empStatus = new ArrayList<String>();
for(Employee emp : empList){
empStatus.add(emp.addJoinString());
responseJSON = GenericOrmStatusView.OrmResponseToJsonString(true, 1,empStatus, true);
}
}
}
return responseJSON;
}
I have the following method defined in my Employee class :
public String addJoinString() {
return String.format("ID: %d",Name: %s," ,this.EmployeeId,this.name);
}
Since I am running a for loop in the code here and sending the list empStatus to the OrmResponseToJsonString method :
for(Employee emp : empList){
empStatus.add(emp.addJoinString());
responseJSON = GenericOrmStatusView.OrmResponseToJsonString(true, 1,empStatus, true);
I am getting the following JSON response :
{
"status" : "SUCCESS",
"employeeStatus" : [ "ID: 81, Name: Jack", "ID: 83, Name: Anthony", "ID: 88, Name: Stephanie", "ID: 25, Name: Kelly", "ID: 02, Name: Jessica" ]
}
However, I would like to be it in the following format:
{
"status" : "SUCCESS",
"message": " "
},
"employeeStatus":[{
"ID":81,
"Name":"Jack"
},
{
"ID":88,
"Name":"Anthony"
},
and so on and so forth ....
]
For Reference:
My OrmResponseToJsonString method is defined as follows inside GenericOrmStatusView class
public class GenericOrmStatusView extends Views
{
public static String OrmResponseToJsonString(boolean success, List<String> eStatus,boolean pretty)
{
PrintemployeeStatusIDAndStatus statusMsg = WebServiceUtils.printNameAndID(success, eStatus);
String genericOrmStatusJsonString = null;
try {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, pretty);
genericOrmStatusJsonString = objectMapper.writerWithView(Views.Normal.class).writeValueAsString(statusMsg);
//genericOrmStatusJsonString = objectMapper.writerWithView(Views.Normal.class).writeValueAsString(eStatus);
} catch(Exception e) {
e.printStackTrace();
}
return genericOrmStatusJsonString;
}
}
And my printNameAndID method is defined as follows inside WebServiceUtils class :
public class WebServiceUtils
{
public static PrintNameAndID printNameAndID(boolean success, List<String> eStatus)
{
PrintNameAndID statusMsgAndRegID = new PrintNameAndID();
if (success) {
statusMsgAndRegID.setStatus("SUCCESS");
statusMsgAndRegID.setemployeeStatus(eStatus);
} else {
statusMsgAndRegID.setStatus("ERROR");
//statusMsgAndRegID.setemployeeStatus("");
}
return statusMsgAndRegID;
}
}
The easiest way to get desired JSON output, is to create an object model representing the data, e.g.
public class MyJSON {
private MyStatus status;
private List<EmployeeStatus> employeeStatus = new ArrayList<>();
public MyJSON(String status, String message) {
this.status = new MyStatus(status, message);
}
public void addEmployeeStatus(int id, String name) {
this.employeeStatus.add(new EmployeeStatus(id, name));
}
public MyStatus getStatus() {
return this.status;
}
public List<EmployeeStatus> getEmployeeStatus() {
return this.employeeStatus;
}
}
public class MyStatus {
private String status;
private String message;
public MyStatus(String status, String message) {
this.status = status;
this.message = message;
}
public String getStatus() {
return this.status;
}
public String getMessage() {
return this.message;
}
}
public class EmployeeStatus {
private int id;
private String name;
public EmployeeStatus(int id, String name) {
this.id = id;
this.name = name;
}
#JsonProperty("ID")
public int getId() {
return this.id;
}
#JsonProperty("Name")
public String getName() {
return this.name;
}
}
You can then create JSON text like this:
MyJSON myJSON = new MyJSON("SUCCESS", " ");
myJSON.addEmployeeStatus(81, "Jack");
myJSON.addEmployeeStatus(88, "Anthony");
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
String json = objectMapper.writeValueAsString(myJSON);
System.out.println(json);
Output
{
"status" : {
"status" : "SUCCESS",
"message" : " "
},
"employeeStatus" : [ {
"ID" : 81,
"Name" : "Jack"
}, {
"ID" : 88,
"Name" : "Anthony"
} ]
}
As mentioned by chrylis in a comment:
As a note, you can normally let Spring do this automatically and just return empList from your controller method.
Which for the above code would mean something like this:
#GetMapping(path="/foo", produces="application/json")
public MyJSON foo() {
MyJSON myJSON = new MyJSON("SUCCESS", " ");
myJSON.addEmployeeStatus(81, "Jack");
myJSON.addEmployeeStatus(88, "Anthony");
return myJSON;
}

Android Dynamic response type Retroft

hello i have Json response like this
[
{
"question": "hhhhh",
"question_answer": "hhhh ",
"question_type": "question type",
"questioner_age": "questioner age",
"questioner_city": "questioner city",
"questioner_country": "questioner country",
"questioner_name": "questioner name",
"questioner_sex": "questioner sex",
"comments_allowed": "1",
"question_id": "63",
"question_date": "05/08/2017 - 19:33",
"is_public": "1"
},
{
"question": "hhhh !!",
"question_answer": "hhhh",
"question_type": [],
"questioner_age": [],
"questioner_city": [],
"questioner_country": [],
"questioner_name": "hhhhh",
"questioner_sex": [],
"comments_allowed": "1",
"question_id": "57",
"question_date": "04/30/2017 - 14:24",
"is_public": "1"
}
]
if the column is null will return as an array like this "question_type": [],
if not will return as a string !
so i tried to get this response on retrofit but i failed and always got this error
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 4 column 2 path $
after i searched in the internet i tried something like this but its not working !!
Gson gson = new Gson();
String json = response.body().toString();
if (json instanceof String)
{
MyQuestionModelString parseObject = gson.fromJson(json, MyQuestionModelString.class);
apiCallResponse.onSuccess(parseObject,responseMessage);
}else {
MyQuestionModel parseObject = gson.fromJson(json, MyQuestionModel.class);
apiCallResponse.onSuccess(parseObject,responseMessage);
}
any help !
UPDATAE !
this is my model for this response and same error !!!
public class MyQuestionModel {
#SerializedName("question")
#Expose
private String question;
#SerializedName("question_answer")
#Expose
private String questionAnswer;
#SerializedName("question_type")
#Expose
private List<Object> questionType = null;
#SerializedName("questioner_age")
#Expose
private List<Object> questionerAge = null;
#SerializedName("questioner_city")
#Expose
private List<Object> questionerCity = null;
#SerializedName("questioner_country")
#Expose
private List<Object> questionerCountry = null;
#SerializedName("questioner_name")
#Expose
private String questionerName;
#SerializedName("questioner_sex")
#Expose
private List<Object> questionerSex = null;
#SerializedName("comments_allowed")
#Expose
private String commentsAllowed;
#SerializedName("question_id")
#Expose
private String questionId;
#SerializedName("question_date")
#Expose
private String questionDate;
#SerializedName("is_public")
#Expose
private String isPublic;
}
My Main issue that how to define this field ! question_type
screen shot
During the parsing of json if the SerializedName key is not found it will throw an exception. Use #Expose to let the deserializer to know that this field can be null. Here is a similar Model of your mentioned response
public class ResponsePojo {
List<Data> data;
public class Data {
#Expose
#SerializedName("question")
String question;
#Expose
#SerializedName("question_answer")
String questionAnswer;
#Expose
#SerializedName("question_type")
String questionType;
#Expose
#SerializedName("questioner_age")
String questionerAge;
#Expose
#SerializedName("questioner_city")
String questionerCity;
#Expose
#SerializedName("questioner_country")
String questionerCountry;
#Expose
#SerializedName("questioner_name")
String questionerName;
#Expose
#SerializedName("questioner_sex")
String questionerSex;
#Expose
#SerializedName("comments_allowed")
String commentsAllowed;
#Expose
#SerializedName("question_id")
String questionId;
#Expose
#SerializedName("question_date")
String questionDate;
#Expose
#SerializedName("is_public")
String isPublic;
}
}
You must indicate which paramters or objects in the model are optional with #Exposed tag.
Example
#Expose
#SerializedName("question_type")
private String mQuestionType;
You problem is
ava.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 4 column 2 path $
If your json code is [...],your return is JSONArray , you can use Gsonto parse it to List<Object> .
If your json code is {...},your return is JSONObject , you can use Gsonto parse it to Object .
So you should use List<MyQuestionModel> to get parsed data .
Change MyQuestionModel to List<MyQuestionModel> in your call code .
Sample
Call<List<MyQuestionModel>> getData();
And my code for doing it .
JSONEntity for you json
public class JSONEntity {
/**
* question : hhhhh
* question_answer : hhhh
* question_type : question type
* questioner_age : questioner age
* questioner_city : questioner city
* questioner_country : questioner country
* questioner_name : questioner name
* questioner_sex : questioner sex
* comments_allowed : 1
* question_id : 63
* question_date : 05/08/2017 - 19:33
* is_public : 1
*/
private String question;
private String question_answer;
private String question_type;
private String questioner_age;
private String questioner_city;
private String questioner_country;
private String questioner_name;
private String questioner_sex;
private String comments_allowed;
private String question_id;
private String question_date;
private String is_public;
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getQuestion_answer() {
return question_answer;
}
public void setQuestion_answer(String question_answer) {
this.question_answer = question_answer;
}
public String getQuestion_type() {
return question_type;
}
public void setQuestion_type(String question_type) {
this.question_type = question_type;
}
public String getQuestioner_age() {
return questioner_age;
}
public void setQuestioner_age(String questioner_age) {
this.questioner_age = questioner_age;
}
public String getQuestioner_city() {
return questioner_city;
}
public void setQuestioner_city(String questioner_city) {
this.questioner_city = questioner_city;
}
public String getQuestioner_country() {
return questioner_country;
}
public void setQuestioner_country(String questioner_country) {
this.questioner_country = questioner_country;
}
public String getQuestioner_name() {
return questioner_name;
}
public void setQuestioner_name(String questioner_name) {
this.questioner_name = questioner_name;
}
public String getQuestioner_sex() {
return questioner_sex;
}
public void setQuestioner_sex(String questioner_sex) {
this.questioner_sex = questioner_sex;
}
public String getComments_allowed() {
return comments_allowed;
}
public void setComments_allowed(String comments_allowed) {
this.comments_allowed = comments_allowed;
}
public String getQuestion_id() {
return question_id;
}
public void setQuestion_id(String question_id) {
this.question_id = question_id;
}
public String getQuestion_date() {
return question_date;
}
public void setQuestion_date(String question_date) {
this.question_date = question_date;
}
public String getIs_public() {
return is_public;
}
public void setIs_public(String is_public) {
this.is_public = is_public;
}
}
And the code for parse it .
Gson gson = new Gson();
String jsonString = response.body().string();
Type type = new TypeToken<List<JSONEntity>>() {
}.getType();
List<JSONEntity> datas = gson.fromJson(jsonString, type);
EDIT
If your response is JSONArray , you can try like this .
List<JSONEntity> datas = response.body();
Try to change your JSON Structure
First Approach
To
If the column is null return "question_type": null,else show "question_type": "value"
Instead
If the column is null will return as an array like this "question_type": [], if not will return as a string!
Second Approach Without changing Json structure
Handling Dynamic JSON Using Gson
Try this:
You have to use deserialize to parse dynamic datatype in json
In the reponse pojo use object
Ex:
Call<Object> call = //your API call ResponsePojo instead use `Object`
call.enqueue(new Callback<Object>()
{
#Override
public void onResponse(Response<Object> response, Retrofit retrofit)
{
try {
JSONArray jsonArray=new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(ServerResponse.class, new ServerResponse.OptionsDeserilizer())
.create();
ServerResponse serverResponse=gson.fromJson(jsonArray.get(i).toString(), ServerResponse.class);
System.out.println(serverResponse);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t)
{
///Handle failure
}
});
Use this ServerResponsePojo with JsonDeserializer
import android.text.TextUtils;
import com.google.gson.Gson;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
public class ServerResponse {
#SerializedName("question")
#Expose
private String question;
#SerializedName("question_answer")
#Expose
private String questionAnswer;
private String questionerName;
#SerializedName("comments_allowed")
#Expose
private String commentsAllowed;
#SerializedName("question_id")
#Expose
private String questionId;
#SerializedName("question_date")
#Expose
private String questionDate;
#SerializedName("is_public")
#Expose
private String isPublic;
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getQuestionAnswer() {
return questionAnswer;
}
public void setQuestionAnswer(String questionAnswer) {
this.questionAnswer = questionAnswer;
}
/* public List<OptionValue> getQuestionerAge() {
return questionerAge;
}
public void setQuestionerAge(List<OptionValue> questionerAge) {
this.questionerAge = questionerAge;
}
public List<OptionValue> getQuestionerCity() {
return questionerCity;
}
public void setQuestionerCity(List<OptionValue> questionerCity) {
this.questionerCity = questionerCity;
}
public List<OptionValue> getQuestionerCountry() {
return questionerCountry;
}
public void setQuestionerCountry(List<OptionValue> questionerCountry) {
this.questionerCountry = questionerCountry;
}
*/
public String getQuestionerName() {
return questionerName;
}
public void setQuestionerName(String questionerName) {
this.questionerName = questionerName;
}
/*
public List<OptionValue> getQuestionerSex() {
return questionerSex;
}
public void setQuestionerSex(List<OptionValue> questionerSex) {
this.questionerSex = questionerSex;
}*/
public String getCommentsAllowed() {
return commentsAllowed;
}
public void setCommentsAllowed(String commentsAllowed) {
this.commentsAllowed = commentsAllowed;
}
public String getQuestionId() {
return questionId;
}
public void setQuestionId(String questionId) {
this.questionId = questionId;
}
public String getQuestionDate() {
return questionDate;
}
public void setQuestionDate(String questionDate) {
this.questionDate = questionDate;
}
public String getIsPublic() {
return isPublic;
}
public void setIsPublic(String isPublic) {
this.isPublic = isPublic;
}
public class OptionValue {
}
public void setQuestionType(String questionType) {
this.questionType = questionType;
}
String questionType;
public static class OptionsDeserilizer implements JsonDeserializer<ServerResponse> {
#Override
public ServerResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Type listType = new TypeToken<ServerResponse>() {
}.getType();
ServerResponse options = (ServerResponse) new Gson().fromJson(json, listType);
JsonObject jsonArrayValue = json.getAsJsonObject();
for (int i = 0; i < jsonArrayValue.size(); i++) {
JsonObject jsonObject = jsonArrayValue.getAsJsonObject();
if (jsonObject.has("question_type")) {
JsonElement elem = (JsonElement) jsonObject.get("question_type");
if (elem != null && !elem.isJsonNull() && !elem.isJsonArray()) {
String valuesString = elem.getAsString();
if (!TextUtils.isEmpty(valuesString)) {
options.setQuestionType(valuesString);
} else {
options.setQuestionType("");
}
//Do your other stuffs
}
}
}
return options;
}
}
}
This is working happy codeing

Deserializing JSON array of objects using GSON

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());

Deserializing json with various keys as value

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.

Unable to add array element under array using JSON

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")

Categories

Resources