How can I get the GSON library to correctly convert the below JSON string to objects. I've tried for ages but it only seems to pick out the 2 "Word" objects and leave the member fields blank or null.
JSON:
{
"words": [
{
"Word": {
"id": "1",
"word": "submarine",
"word_syllables": "sub-mar-ine",
"picture": "none.jpg",
"soundfile": "",
"user_id": "1"
}
},
{
"Word": {
"id": "2",
"word": "computer",
"word_syllables": "com-pute-r",
"picture": "computer.jpg",
"soundfile": "",
"user_id": "0"
}
}
]
}
I thought that the above could be created simply by having a class called "Words" which contains an arraylist/list of Word objects.
The Words class;
package com.example.testgson.business;
import java.util.ArrayList;
import java.util.List;
import android.util.Log;
public class Words {
public List<Word> words=new ArrayList<Word>();
public Words(){
}
public int size(){
return words.size();
}
public void addWord(Word w){
this.words.add(w);
}
public List<Word> getWords() {
return words;
}
public void setWords(List<Word> words) {
this.words = words;
}
public void printAll(){
for(int i=0; i<words.size();i++){
Word w=(Word) words.get(i);
if(w!=null){
Log.d("word",w.getWord());
}
}
}
public List <Word> getWordList(){
return this.words;
}
}
The Word Class;
public class Word {
int id;
String word;
String word_syllables;
String picture;
String soundfile;
int user_id;
public Word(){
}
public Word(int id, String word, String word_syllables, String picture,
String soundfile, int user_id) {
super();
this.id = id;
this.word = word;
this.word_syllables = word_syllables;
this.picture = picture;
this.soundfile = soundfile;
this.user_id = user_id;
}
#Override
public String toString() {
return "Word [id=" + id + ", word=" + word + ", word_syllables="
+ word_syllables + ", picture=" + picture + ", soundfile="
+ soundfile + ", user_id=" + user_id + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getWord() {
return this.word;
}
public void setWord(String word) {
this.word = word;
}
public String getWord_syllables() {
return word_syllables;
}
public void setWord_syllables(String word_syllables) {
this.word_syllables = word_syllables;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getSoundfile() {
return soundfile;
}
public void setSoundfile(String soundfile) {
this.soundfile = soundfile;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
}
GSON convert code;
Gson gson = new Gson();
Words obj = gson.fromJson(sjson, Words.class);
You need to skip one level, because you array is not a List<Word> but a List<Holder> where the Holder class has a Word instance. You can either create this class, or write a custom deserializer to skip it:
class CustomDeserializer implements JsonDeserializer<Word> {
#Override
public Word deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException {
JsonElement content = je.getAsJsonObject().get("Word");
return new Gson().fromJson(content, type);
}
}
and then:
Gson gson = new GsonBuilder().registerTypeAdapter(Word.class, new CustomDeserializer()).create();
which yields:
Word [id=1, word=submarine, word_syllables=sub-mar-ine, picture=none.jpg, soundfile=, user_id=1]
Word [id=2, word=computer, word_syllables=com-pute-r, picture=computer.jpg, soundfile=, user_id=0]
Related
I have json data regarding student details,That i want to print in respective textviews. i'm new to json services please help me to print the this data on screen.I'm using getters and setters for subject score so further i want to use them dynamically.
here is my json data
{
"studentInfo": {
"studentName": "srini#gmail.com",
"studentId": "abc",
"date": 14102017,
"JanuaryScoreCard" : {
"english" : "44",
"Science" : "45",
"maths": "66",
"social" : "56",
"hindi" : "67",
"kannada" : "78",
},
"MarchScoreCard" : {
" english " : "54",
" Science " : "56",
" maths ": "70",
" social " : "87",
" hindi " : "98",
" kannada " : "56"
},
"comments" : ""
}
I'm Something to print but could not,i don't where i'm going wrong
public void init()
{
try {
parseJSON();
} catch (JSONException e)
{
e.printStackTrace();
}
}
public void parseJSON() throws JSONException{
jsonObject = new JSONObject(strJson);
JSONObject object = jsonObject.getJSONObject("studentInfo");
patientName = object.getString("studentName");
patientID = object.getString("studentId");
mName.setText(studentName);
mUserId.setText(studentId);
}
You can use JSON parser and then you can print any data you want from that,
Use GSON for this, here is an example https://www.javacodegeeks.com/2011/01/android-json-parsing-gson-tutorial.html
Here is a basic JSON Parsing process
public void parseJson() {
String your_response = "replace this with your response";
try {
JSONObject jsonObject = new JSONObject(your_response);
JSONObject studentInfoJsonObject = jsonObject.getJSONObject("studentInfo");
StudentInfo studentInfo1 = new StudentInfo();
studentInfo1.setStudentName(studentInfoJsonObject.optString("studentName"));
studentInfo1.setStudentId(studentInfoJsonObject.optString("studentId"));
studentInfo1.setDate(studentInfoJsonObject.optString("date"));
studentInfo1.setComments(studentInfoJsonObject.optString("comments"));
JSONObject januaryScoreCardJsonObject = studentInfoJsonObject.optJSONObject("JanuaryScoreCard");
JanuaryScoreCard januaryScoreCard1 = new JanuaryScoreCard();
januaryScoreCard1.setEnglish(januaryScoreCardJsonObject.optString("english"));
januaryScoreCard1.setHindi(januaryScoreCardJsonObject.optString("hindi"));
januaryScoreCard1.setMaths(januaryScoreCardJsonObject.optString("maths"));
januaryScoreCard1.setSocial(januaryScoreCardJsonObject.optString("social"));
januaryScoreCard1.setKannada(januaryScoreCardJsonObject.optString("kannada"));
januaryScoreCard1.setScience(januaryScoreCardJsonObject.optString("Science"));
JSONObject marchScoreCardJsonObject = studentInfoJsonObject.optJSONObject("JanuaryScoreCard");
MarchScoreCard marchScoreCard = new MarchScoreCard();
marchScoreCard.setEnglish(marchScoreCardJsonObject.optString("english"));
marchScoreCard.setHindi(marchScoreCardJsonObject.optString("hindi"));
marchScoreCard.setMaths(marchScoreCardJsonObject.optString("maths"));
marchScoreCard.setSocial(marchScoreCardJsonObject.optString("social"));
marchScoreCard.setKannada(marchScoreCardJsonObject.optString("kannada"));
marchScoreCard.setScience(marchScoreCardJsonObject.optString("Science"));
studentInfo1.setJanuaryScoreCard(januaryScoreCard1);
studentInfo1.setMarchScoreCard(marchScoreCard);
} catch (JSONException e) {
e.printStackTrace();
}
}
Student Info Class
public class StudentInfo {
private String studentName;
private String studentId;
private String date;
private String comments;
private JanuaryScoreCard januaryScoreCard;
private MarchScoreCard marchScoreCard;
public JanuaryScoreCard getJanuaryScoreCard() {
return januaryScoreCard;
}
public void setJanuaryScoreCard(JanuaryScoreCard januaryScoreCard) {
this.januaryScoreCard = januaryScoreCard;
}
public MarchScoreCard getMarchScoreCard() {
return marchScoreCard;
}
public void setMarchScoreCard(MarchScoreCard marchScoreCard) {
this.marchScoreCard = marchScoreCard;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
}
and Here is January class
public class JanuaryScoreCard {
private String english;
private String Science;
private String maths;
private String kannada;
private String social;
private String hindi;
public String getEnglish() {
return english;
}
public void setEnglish(String english) {
this.english = english;
}
public String getScience() {
return Science;
}
public void setScience(String science) {
Science = science;
}
public String getMaths() {
return maths;
}
public void setMaths(String maths) {
this.maths = maths;
}
public String getKannada() {
return kannada;
}
public void setKannada(String kannada) {
this.kannada = kannada;
}
public String getSocial() {
return social;
}
public void setSocial(String social) {
this.social = social;
}
public String getHindi() {
return hindi;
}
public void setHindi(String hindi) {
this.hindi = hindi;
}
}
and Here is March Class
public class MarchScoreCard{
private String english;
private String Science;
private String maths;
private String kannada;
private String social;
private String hindi;
public String getEnglish() {
return english;
}
public void setEnglish(String english) {
this.english = english;
}
public String getScience() {
return Science;
}
public void setScience(String science) {
Science = science;
}
public String getMaths() {
return maths;
}
public void setMaths(String maths) {
this.maths = maths;
}
public String getKannada() {
return kannada;
}
public void setKannada(String kannada) {
this.kannada = kannada;
}
public String getSocial() {
return social;
}
public void setSocial(String social) {
this.social = social;
}
public String getHindi() {
return hindi;
}
public void setHindi(String hindi) {
this.hindi = hindi;
}
}
You need to parse this json Data , For this you need Create appropriate bean classes and put data while parsing json into this bean classes object and create List .
Then you need to create ListView and Adapter for populate data into Screen or Activity.
I have this JSON data and I would like to deserialize it with Android to get it as an object to use in my class.
I get this folowing error :
Could not read JSON: Unrecognized field "card_details"
[
{
"id": "9",
"cat_id": "CAT-8584ce02f180b57a8c6d66570f696e02",
"app_id": "null",
"status": "1",
"lft": "1",
"rgt": "2",
"parent_cat_id": "0",
"added_date": "2017-01-12 12:41:29",
"last_edit_date": "2017-01-12 12:46:09",
"language_id": "0",
"category_id": "CAT-8584ce02f180b57a8c6d66570f696e02",
"name": "Sport",
"description": "This is sport category",
"image": "notitia/USR-70903638005256656/app-content/cat-img-da1161af03df255a989f8df5fc2e15bd.png",
"tags": "",
"custom_url": "sport",
"card_details": {
"nom_carte": "Pinacolada",
"prix": "5000",
"image": "notitia/USR-44043694343417880/app-content/e0fa7beb401e8fe77727f5a8241ff872.jpg",
"validity": "1"
}
}
]
Here is my AsyncTask to retrieve the data:
private class HttpRequestTaskCarte extends AsyncTask<Void,Void,Item[]> {
#Override
protected Item[] doInBackground(Void... params) {
try {
final String url = "http://domain.com/link.php?target=multi";
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Item[] greeting = restTemplate.getForObject(url, Item[].class);
return greeting;
} catch (Exception e) {
//Toast.makeText(getActivity(), "Error Loading !", Toast.LENGTH_SHORT).show();
Log.e("MainActivity", e.getMessage(), e);
}
return null;
}
protected void onPreExecute(){
progressDialog = new ProgressDialog(getActivity(),
R.style.AppTheme_Dark_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("chargement des elements...");
progressDialog.show();
}
#Override
protected void onPostExecute(Item[] greeting) {
Log.d("okokok",""+greeting.length);
progressDialog.dismiss();
}
}
And here is the class that I am using to deserialize:
public class Item {
private List<card_details> carte;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCat_id() {
return cat_id;
}
public void setCat_id(String cat_id) {
this.cat_id = cat_id;
}
public String getApp_id() {
return app_id;
}
public void setApp_id(String app_id) {
this.app_id = app_id;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getLft() {
return lft;
}
public void setLft(String lft) {
this.lft = lft;
}
public String getRgt() {
return rgt;
}
public void setRgt(String rgt) {
this.rgt = rgt;
}
public String getParent_cat_id() {
return parent_cat_id;
}
public void setParent_cat_id(String parent_cat_id) {
this.parent_cat_id = parent_cat_id;
}
public String getAdded_date() {
return added_date;
}
public void setAdded_date(String added_date) {
this.added_date = added_date;
}
public String getLast_edit_date() {
return last_edit_date;
}
public void setLast_edit_date(String last_edit_date) {
this.last_edit_date = last_edit_date;
}
public String getLanguage_id() {
return language_id;
}
public void setLanguage_id(String language_id) {
this.language_id = language_id;
}
public String getCategory_id() {
return category_id;
}
public void setCategory_id(String category_id) {
this.category_id = category_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getTags() {
return tags;
}
public void setTags(String tags) {
this.tags = tags;
}
public String getCustom_url() {
return custom_url;
}
public void setCustom_url(String custom_url) {
this.custom_url = custom_url;
}
public List<Detail_cartes> getCarte() {
return carte;
}
public void setCarte(List<Detail_cartes> carte) {
this.carte = carte;
}
public static class Detail_cartes{
private String nom_carte ;
private String prix ;
private String image ;
private String validity ;
}
}
JSONArray array=new JSONArray(your data);
JSONObject obj=array.getJSONObject(0);
JSONObject cardDetail=obj.getJSONObject("card_details");
Hii u can use the following code:
JSONArray jsonarray = new JSONArray(jsonStr);
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject jsonobject = jsonarray.getJSONObject(i);
String name = jsonobject.getString("name");
String url = jsonobject.getString("url");
}
I have the following JSON string, which I'm supposed to parse to POJO:
{
"Status": "true",
"Result": {
"rows": {
"row": {
"status": true,
"subareas": [
{
"nome": "Associacao Utente",
"id": 9,
"grafs": {
"rows": [
{
"id": 6,
"nome": "AssociacaoUtente",
"tipo": "PIE",
"serv": "MV_AS_UTENTE_POR_NEGOCIO",
"periodo": "ANO"
}
]
}
},
{
"nome": "Chaves",
"id": 60,
"grafs": {
"rows": [
{
"id": 35,
"nome": "ChavesCriadosporano",
"tipo": "LINHA",
"serv": "MV_ASSOC_TOTAL_CHAVES",
"periodo": "ANO"
},
{
"id": 592,
"nome": "ChavesAssociadoAoUserPortal",
"tipo": "BAR",
"serv": "MV_ASSOC_USER_CHAVES",
"periodo": "TODOS"
},
{
"id": 593,
"nome": "ChavesAssociadoAoNegocios",
"tipo": "BAR",
"serv": "MV_ASSOC_CHAVES",
"periodo": "TODOS"
}
]
}
}
]
}
}
}
}
and I have these classes to deserialize to POJO, which is working, thanks to Saurabh:
public class Example {
private String Status;
private Result Result;
public String getStatus() {
return Status;
}
public void setStatus(String status) {
Status = status;
}
public Result getResult() {
return Result;
}
public void setResult(Result result) {
Result = result;
}
#Override
public String toString() {
return "Example [Status=" + Status + ", Result=" + Result + "]";
}
}
public class Result {
private Rows rows;
public Rows getRows() {
return rows;
}
public void setRows(Rows rows) {
this.rows = rows;
}
#Override
public String toString() {
return "Result [rows=" + rows + "]";
}
}
public class Rows {
private Row row;
public Row getRow() {
return row;
}
public void setRow(Row row) {
this.row = row;
}
#Override
public String toString() {
return "Rows [row=" + row + "]";
}
}
import java.util.ArrayList;
import java.util.List;
public class Row {
private Boolean status;
private List<Subarea> subareas = new ArrayList<Subarea>();
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public List<Subarea> getSubareas() {
return subareas;
}
public void setSubareas(List<Subarea> subareas) {
this.subareas = subareas;
}
#Override
public String toString() {
return "Row [status=" + status + ", subareas=" + subareas + "]";
}
}
public class Subarea {
private String nome;
private Integer id;
private Grafs grafs;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Grafs getGrafs() {
return grafs;
}
public void setGrafs(Grafs grafs) {
this.grafs = grafs;
}
#Override
public String toString() {
return "Subarea [nome=" + nome + ", id=" + id + ", grafs=" + grafs
+ "]";
}
}
import java.util.ArrayList;
import java.util.List;
public class Grafs {
private List<Row_> rows = new ArrayList<Row_>();
public List<Row_> getRows() {
return rows;
}
public void setRows(List<Row_> rows) {
this.rows = rows;
}
#Override
public String toString() {
return "Grafs [rows=" + rows + "]";
}
}
public class Row_ {
private Integer id;
private String nome;
private String serv;
private String periodo;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getServ() {
return serv;
}
public void setServ(String serv) {
this.serv = serv;
}
public String getPeriodo() {
return periodo;
}
public void setPeriodo(String periodo) {
this.periodo = periodo;
}
#Override
public String toString() {
return "Row_ [id=" + id + ", nome=" + nome + ", serv=" + serv
+ ", periodo=" + periodo + "]";
}
}
I need help populating the data received from JSON to a recyclerview, divided by sub areas. I'm confused on how to create the adapter.
First, your JSON should have Symmetry (See "grafs" key under "subareas" key) -
In first value it is as -
"grafs" : {
"rows" : {
"row" : {
And in second value it is as -
"grafs" : {
"rows" : [
So, I just made them correct as -
{
"Status": "true",
"Result": {
"rows": {
"row": {
"status": true,
"subareas": [
{
"nome": "Associacao Utente",
"id": 9,
"grafs": {
"rows": [
{
"id": 6,
"nome": "AssociacaoUtente",
"tipo": "PIE",
"serv": "MV_AS_UTENTE_POR_NEGOCIO",
"periodo": "ANO"
}
]
}
},
{
"nome": "Chaves",
"id": 60,
"grafs": {
"rows": [
{
"id": 35,
"nome": "ChavesCriadosporano",
"tipo": "LINHA",
"serv": "MV_ASSOC_TOTAL_CHAVES",
"periodo": "ANO"
},
{
"id": 592,
"nome": "ChavesAssociadoAoUserPortal",
"tipo": "BAR",
"serv": "MV_ASSOC_USER_CHAVES",
"periodo": "TODOS"
},
{
"id": 593,
"nome": "ChavesAssociadoAoNegocios",
"tipo": "BAR",
"serv": "MV_ASSOC_CHAVES",
"periodo": "TODOS"
}
]
}
}
]
}
}
}
}
Now you can create classes as -
Example.java
public class Example {
private String Status;
private Result Result;
public String getStatus() {
return Status;
}
public void setStatus(String status) {
Status = status;
}
public Result getResult() {
return Result;
}
public void setResult(Result result) {
Result = result;
}
#Override
public String toString() {
return "Example [Status=" + Status + ", Result=" + Result + "]";
}
}
Result.java
public class Result {
private Rows rows;
public Rows getRows() {
return rows;
}
public void setRows(Rows rows) {
this.rows = rows;
}
#Override
public String toString() {
return "Result [rows=" + rows + "]";
}
}
Rows.java
public class Rows {
private Row row;
public Row getRow() {
return row;
}
public void setRow(Row row) {
this.row = row;
}
#Override
public String toString() {
return "Rows [row=" + row + "]";
}
}
Row.java
import java.util.ArrayList;
import java.util.List;
public class Row {
private Boolean status;
private List<Subarea> subareas = new ArrayList<Subarea>();
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public List<Subarea> getSubareas() {
return subareas;
}
public void setSubareas(List<Subarea> subareas) {
this.subareas = subareas;
}
#Override
public String toString() {
return "Row [status=" + status + ", subareas=" + subareas + "]";
}
}
Subarea.java
public class Subarea {
private String nome;
private Integer id;
private Grafs grafs;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Grafs getGrafs() {
return grafs;
}
public void setGrafs(Grafs grafs) {
this.grafs = grafs;
}
#Override
public String toString() {
return "Subarea [nome=" + nome + ", id=" + id + ", grafs=" + grafs
+ "]";
}
}
Grafs.java
import java.util.ArrayList;
import java.util.List;
public class Grafs {
private List<Row_> rows = new ArrayList<Row_>();
public List<Row_> getRows() {
return rows;
}
public void setRows(List<Row_> rows) {
this.rows = rows;
}
#Override
public String toString() {
return "Grafs [rows=" + rows + "]";
}
}
Row_.java
public class Row_ {
private Integer id;
private String nome;
private String serv;
private String periodo;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getServ() {
return serv;
}
public void setServ(String serv) {
this.serv = serv;
}
public String getPeriodo() {
return periodo;
}
public void setPeriodo(String periodo) {
this.periodo = periodo;
}
#Override
public String toString() {
return "Row_ [id=" + id + ", nome=" + nome + ", serv=" + serv
+ ", periodo=" + periodo + "]";
}
}
Now, you can test this as below -
Main.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.testgson.beans.Example;
public class Main {
private static Gson gson;
static {
gson = new GsonBuilder().create();
}
/**
* #param args
*/
public static void main(String[] args) {
String j = "{\"Status\":\"true\",\"Result\":{\"rows\":{\"row\":{\"status\":true,\"subareas\":[{\"nome\":\"Associacao Utente\",\"id\":9,\"grafs\":{\"rows\":[{\"id\":6,\"nome\":\"AssociacaoUtente\",\"tipo\":\"PIE\",\"serv\":\"MV_AS_UTENTE_POR_NEGOCIO\",\"periodo\":\"ANO\"}]}},{\"nome\":\"Chaves\",\"id\":60,\"grafs\":{\"rows\":[{\"id\":35,\"nome\":\"ChavesCriadosporano\",\"tipo\":\"LINHA\",\"serv\":\"MV_ASSOC_TOTAL_CHAVES\",\"periodo\":\"ANO\"},{\"id\":592,\"nome\":\"ChavesAssociadoAoUserPortal\",\"tipo\":\"BAR\",\"serv\":\"MV_ASSOC_USER_CHAVES\",\"periodo\":\"TODOS\"},{\"id\":593,\"nome\":\"ChavesAssociadoAoNegocios\",\"tipo\":\"BAR\",\"serv\":\"MV_ASSOC_CHAVES\",\"periodo\":\"TODOS\"}]}}]}}}}";
Example r = gson.fromJson(j, Example.class);
System.out.println(r);
}
}
And the Result is -
Example [Status=true, Result=Result [rows=Rows [row=Row [status=true, subareas=[Subarea [nome=Associacao Utente, id=9, grafs=Grafs [rows=[Row_ [id=6, nome=AssociacaoUtente, serv=MV_AS_UTENTE_POR_NEGOCIO, periodo=ANO]]]], Subarea [nome=Chaves, id=60, grafs=Grafs [rows=[Row_ [id=35, nome=ChavesCriadosporano, serv=MV_ASSOC_TOTAL_CHAVES, periodo=ANO], Row_ [id=592, nome=ChavesAssociadoAoUserPortal, serv=MV_ASSOC_USER_CHAVES, periodo=TODOS], Row_ [id=593, nome=ChavesAssociadoAoNegocios, serv=MV_ASSOC_CHAVES, periodo=TODOS]]]]]]]]]
i have the following Json string, which I'm suppose to deserialize. The problem is: since this string comes from a server I can't change it and I need to deserialize as POJO. You can see that the Grafs keys have different values for each subarea. One is an object an the other an array. How can I handle this?
{
"Status": "true",
"Result: {
"rows": {
"row": {
"status": true,
"subareas": [
{
"nome": "Associacao Utente",
"id": 9,
"grafs": {
"rows": {
"id": 6,
"nome": "Associacao Utente",
"tipo": "PIE",
"serv": "MV_AS_UTENTE_POR_NEGOCIO",
"periodo": "ANO"
}
}
}, {
"nome": "Chaves",
"id": 60,
"grafs": {
"rows": [
{
"id": 35,
"nome": "Chaves Criados por ano",
"tipo": "LINHA",
"serv": "MV_ASSOC_TOTAL_CHAVES",
"periodo": "ANO"
}, {
"id": 592,
"nome": "Chaves Associado Ao User Portal",
"tipo": "BAR",
"serv": "MV_ASSOC_USER_CHAVES",
"periodo": "TODOS"
}, {
"id": 593,
"nome": "Chaves Associado Ao Negocios",
"tipo": "BAR",
"serv": "MV_ASSOC_CHAVES",
"periodo": "TODOS"
}
]
}
}
]
}
}
}
}
Here follows my classes.
public class Example {
private String Status;
private Result Result;
public String getStatus() {
return Status;
}
public void setStatus(String status) {
Status = status;
}
public Result getResult() {
return Result;
}
public void setResult(Result result) {
Result = result;
}
#Override
public String toString() {
return "Example [Status=" + Status + ", Result=" + Result + "]";
}
}
public class Result {
private Rows rows;
public Rows getRows() {
return rows;
}
public void setRows(Rows rows) {
this.rows = rows;
}
#Override
public String toString() {
return "Result [rows=" + rows + "]";
}
}
public class Grafs {
private List<Rows_> rows = new ArrayList<>();
public List<Rows_> getRows() {
return rows;
}
public void setRows(List<Rows_> Rows) {
this.rows = Rows;
}
#Override
public String toString() {
return "Grafs [rows=" + rows + "]";
}
}
public class Row {
private Boolean status;
private List<Subarea> subareas = new ArrayList<>();
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public List<Subarea> getSubareas() {
return subareas;
}
public void setSubareas(List<Subarea> subareas) {
this.subareas = subareas;
}
#Override
public String toString() {
return "Row [status=" + status + ", subareas=" + subareas + "]";
}
}
public class Row_ {
private Integer id;
private String nome;
private String serv;
private String periodo;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getServ() {
return serv;
}
public void setServ(String serv) {
this.serv = serv;
}
public String getPeriodo() {
return periodo;
}
public void setPeriodo(String periodo) {
this.periodo = periodo;
}
#Override
public String toString() {
return "Row_ [id=" + id + ", nome=" + nome + ", serv=" + serv
+ ", periodo=" + periodo + "]";
}
}
public class Rows {
private Row row;
public Row getRow() {
return row;
}
public void setRow(Row row) {
this.row = row;
}
#Override
public String toString() {
return "Rows [row=" + row + "]";
}
}
public class Rows_ {
private Row_ row;
public Row_ getRow() {
return row;
}
public void setRow(Row_ row) {
this.row = row;
}
}
public class Subarea {
private String nome;
private Integer id;
private Grafs grafs;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Grafs getGrafs() {
return grafs;
}
public void setGrafs(Grafs grafs) {
this.grafs = grafs;
}
#Override
public String toString() {
return "Subarea [nome=" + nome + ", id=" + id + ", grafs=" + grafs
+ "]";
}
}
Using these classes I'm getting the following error:
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 13 column 18.
I declared Rows_ as an arraylist and it encounters an object instead. But the second Rows_ is an array indeed. How can i address this?
Arrays with one element should still be rendered as arrays. That's why I used arrays. But it's giving the error I described.
Thanks for your help. I really appreciate it.
You can use TypeAdapterFactory to do the conversion. Here is a factory that will add that functionality to all of your List member types --
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
public class SingletonListTypeAdapterFactory implements TypeAdapterFactory {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
if (typeToken.getRawType() != List.class
|| !(type instanceof ParameterizedType)) {
return null;
}
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
TypeAdapter<?> elementAdapter = gson.getAdapter(TypeToken.get(elementType));
TypeAdapter<T> arrayAdapter = gson.getDelegateAdapter(this, typeToken);
return (TypeAdapter<T>) newSingtonListAdapter((TypeAdapter<Object>) elementAdapter, (TypeAdapter<List<Object>>) arrayAdapter);
}
private <E> TypeAdapter<List<E>> newSingtonListAdapter(
final TypeAdapter<E> elementAdapter,
final TypeAdapter<List<E>> arrayAdapter) {
return new TypeAdapter<List<E>>() {
public void write(JsonWriter out, List<E> value) throws IOException {
if(value == null || value.isEmpty()) {
out.nullValue();
} else if(value.size() == 1) {
elementAdapter.write(out, value.get(0));
} else {
arrayAdapter.write(out, value);
}
}
public List<E> read(JsonReader in) throws IOException {
if (in.peek() != JsonToken.BEGIN_ARRAY) {
E obj = elementAdapter.read(in);
return Collections.singletonList(obj);
}
return arrayAdapter.read(in);
}
};
}
}
As bonus, it also serializes in the same way, if needed. If you also want to serialize as array, replace the write method with a call to arrayAdapter.write.
To you, add to your gson when building --
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new SingletonListTypeAdapterFactory())
.create();
I am trying to parse the data into a class.
But the problem is that one of the values is in Json format.
Hence I am getting a MalformedJsonException.
This is the Json string:
{
"name": "Check on Server Health ",
"state": "ABORTED",
"startTime": 1332962596131,
"triggeredBy": "GUI_MANUAL",
"completionPct": 25,
"currentStep": "sayHello",
"processDefId": "SW21SW",
"jobRetries": 0,
"businessKey": -1,
"comments": "couldn't instantiate class com.mikewidgets.helloWorld.HelloWorldTask",
"endTime": null,
"status": "DELAY , ERR",
"mtId": "MOTOROLA",
"instParms": "{"message":"start-workflow","sender":"CLI_APP","receiver":"BPM_ENG","parameters":{"workflowId":"SW21SW","mikesname":"Mikeeeeeeey","wf_HostName":"localhost","triggeredBy":"GUI_MANUAL","replyQueue":"temp-queue: //ID: SW-Demo01-51605-1332362748085-0: 2246: 1"},"userId":"Ab","mtId":"MOTOROLA","messageType":"MESSAGE_MSG"}",
"execId": "292",
"startUserId": "Ab"
}
This is the bean class I am using:
import com.google.gson.JsonElement;
public class WfActive {
private String name;
private String state;
private String startTime;
private String status;
private String endTime;
private String comments;
private String triggeredBy;
private String execId;
private JsonElement instParms;
private String startUserId;
private String mtId;
private String businessKey;
private String completionPct;
private String jobRetries;
private String processDefId;
private String currentStep;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public String getTriggeredBy() {
return triggeredBy;
}
public void setTriggeredBy(String triggeredBy) {
this.triggeredBy = triggeredBy;
}
public String getExecId() {
return execId;
}
public void setExecId(String execId) {
this.execId = execId;
}
public JsonElement getInstParms() {
return instParms;
}
public void setInstParms(JsonElement instParms) {
this.instParms = instParms;
}
public String getStartUserId() {
return startUserId;
}
public void setStartUserId(String startUserId) {
this.startUserId = startUserId;
}
public String getMtId() {
return mtId;
}
public void setMtId(String mtId) {
this.mtId = mtId;
}
public String getBusinessKey() {
return businessKey;
}
public void setBusinessKey(String businessKey) {
this.businessKey = businessKey;
}
public String getCompletionPct() {
return completionPct;
}
public void setCompletionPct(String completionPct) {
this.completionPct = completionPct;
}
public String getJobRetries() {
return jobRetries;
}
public void setJobRetries(String jobRetries) {
this.jobRetries = jobRetries;
}
public String getProcessDefId() {
return processDefId;
}
public void setProcessDefId(String processDefId) {
this.processDefId = processDefId;
}
public String getCurrentStep() {
return currentStep;
}
public void setCurrentStep(String currentStep) {
this.currentStep = currentStep;
}
}
But I am getting a Malformed exception at :
LA","instParms":"{"message":"start-workf // this is inside instParms
What is my mistake and how do I correct it?
Please forgive the big code, the interesting part is "instParms"
Your JSON data is malformed (middle line below):
"mtId": "MOTOROLA",
"instParms": "{"message":"start-workflow","sender":"CLI_APP","receiver":"BPM_ENG","parameters":{"workflowId":"SW21SW","mikesname":"Mikeeeeeeey","wf_HostName":"localhost","triggeredBy":"GUI_MANUAL","replyQueue":"temp-queue: //ID: SW-Demo01-51605-1332362748085-0: 2246: 1"},"userId":"Ab","mtId":"MOTOROLA","messageType":"MESSAGE_MSG"}",
"execId": "292",
Second double quote in the value of instParms should be escaped. Alternatively, one could use single quotes instead if you know that single quotes aren't used in the value.
This is valid:
"mtId": "MOTOROLA",
"instParms": '{"message":"start-workflow","sender":"CLI_APP","receiver":"BPM_ENG","parameters":{"workflowId":"SW21SW","mikesname":"Mikeeeeeeey","wf_HostName":"localhost","triggeredBy":"GUI_MANUAL","replyQueue":"temp-queue: //ID: SW-Demo01-51605-1332362748085-0: 2246: 1"},"userId":"Ab","mtId":"MOTOROLA","messageType":"MESSAGE_MSG"}',
"execId": "292",
and so is this:
"mtId": "MOTOROLA",
"instParms": "{\"message\":\"start-workflow\",\"sender\":\"CLI_APP\",\"receiver\":\"BPM_ENG\",\"parameters\":{\"workflowId\":\"SW21SW\",\"mikesname\":\"Mikeeeeeeey\",\"wf_HostName\":\"localhost\",\"triggeredBy\":\"GUI_MANUAL\",\"replyQueue\":\"temp-queue: //ID: SW-Demo01-51605-1332362748085-0: 2246: 1\"},\"userId\":\"Ab\",\"mtId\":\"MOTOROLA\",\"messageType\":\"MESSAGE_MSG\"}",
"execId": "292",
Another alternative would be to embed the value of instParms as a subobject rather than a stirng:
"mtId": "MOTOROLA",
"instParms": {
"message": "start-workflow",
"sender": "CLI_APP",
"receiver": "BPM_ENG",
"parameters": {
"workflowId": "SW21SW",
"mikesname": "Mikeeeeeeey",
"wf_HostName":"localhost",
"triggeredBy":"GUI_MANUAL",
"replyQueue":"temp-queue: //ID: SW-Demo01-51605-1332362748085-0: 2246: 1"
},
"userId": "Ab",
"mtId": "MOTOROLA",
"messageType": "MESSAGE_MSG"
},
"execId": "292",
This is arguably the best solution (unless there is some other compelling reason to keep the string representation).
You can't readily fix it in the code consuming the JSON, nor should you. You need to fix the other end, which is generating invalid JSON. It looks like just an erroneous quote prior to the { on the value for instParms and after the } at the end of it. That, or the entire instParms value really is meant to be a string, and the string hasn't been properly escaped (quotes preceded with backslashes, etc.).