C
I recently started working with GSON and somewhat complex data models, with related classes.The truth is that at first it was not very clear how to do things, what helped me was to safeguard the entire data model as I had designed in each table and build my JSON according to that model, respecting the reality of data.I allow myself to present a somewhat long and complex model, but it can help to face the problem in a complete way, as it includes in many nesting data points at more than one level.The JSON produced is the following:{
"breviario": {
"metaLiturgia": {
"fecha" : "Domingo 25 de noviembre del 2018",
"tiempo" : "TIEMPO ORDINARIO",
"semana" : "Semana XXXIV",
"mensaje": "",
"salterio": "<small></small>",
"color": 0,
"meta":0,
"idTiempo": "08"
},
"santo": {
"nombre": "",
"vida": ""
},
"visperas": {
"himno" : {
"texto": "Oh príncipe absoluto de los siglos,~oh Jesucristo, rey de las naciones:~te confesamos árbitro supremo~de las mentes y de los corazones.§En la tierra te adoran los mortales~y los santos te alaban en el cielo,~unidos a sus voces te aclamamos~proclamándote rey del universo.§Oh Jesucristo, príncipe pacífico:~somete a los espíritus rebeldes,~y haz que encuentren el rumbo los perdidos~y que en un solo aprisco se congreguen.§Para eso pendes de una cruz sangrienta,~y abres en ella tus divinos brazos;~para eso muestras en tu pecho herido~tu ardiente corazón atravesado.§Para eso estás oculto en los altares~tras las imágenes del pan y el vino;~para eso viertes de tu pecho abierto~sangre de salvación para tus hijos.§Por regir con amor el universo,~glorificado seas, Jesucristo,~y que contigo y con tu eterno Padre~también reciba gloria el Santo Espíritu. Amén."
},
"salmodia": {
"tipo":0,
"salmoCompleto": [
{
"orden": "1",
"antifona": "Se sentará sobre el trono de David para reinar eternamente. Aleluya.",
"ref": "Salmo 109, 1-5. 7",
"tema": "El Mesías, Rey y Sacerdote",
"intro": "Él debe reinar hasta poner~todos sus enemigos bajo sus pies.~(1Co 15, 25)",
"parte": "",
"salmo": "Oráculo del Señor a mi Señor:_«Siéntate a mi derecha,_y haré de tus enemigos estrado de tus pies.»§Desde Sión extenderá el Señor_el poder de tu cetro:_somete en la batalla a tus enemigos.§«Eres príncipe desde el día de tu nacimiento,_entre esplendores sagrados;_yo mismo te engendré, como rocío,_antes de la aurora.»§El Señor lo ha jurado y no se arrepiente:_«Tú eres sacerdote eterno,_según el rito de Melquisedec.»§El Señor a tu derecha, el día de su ira,_quebrantará a los reyes.§En su camino beberá del torrente,_por eso levantará la cabeza."
},
{
"orden": "2",
"antifona": "Tu reinado es un reinado perpetuo, tu gobierno va de edad en edad.",
"ref": "Salmo 144, 1-13b",
"tema": "",
"intro": "",
"parte": "",
"salmo": "Te ensalzaré, Dios mío, mi rey;_bendeciré tu nombre por siempre jamás._Día tras día te bendeciré_y alabaré tu nombre por siempre jamás.§Grande es el Señor, merece toda alabanza,_es incalculable su grandeza;_una generación pondera tus obras a la otra,_y le cuenta tus hazañas.§Alaban ellos la gloria de tu majestad,_y yo repito tus maravillas;_encarecen ellos tus temibles proezas,_y yo narro tus grandes acciones;_difunden la memoria de tu inmensa bondad,_y aclaman tus victorias.§El Señor es clemente y misericordioso,_lento a la cólera y rico en piedad;_el Señor es bueno con todos,_es cariñoso con todas sus creaturas.§Que todas tus creaturas te den gracias, Señor,_que te bendigan tus fieles;_que proclamen la gloria de tu reinado,_que hablen de tus hazañas;§explicando tus proezas a los hombres,_la gloria y majestad de tu reinado._Tu reinado es un reinado perpetuo,_tu gobierno va de edad en edad."
},
{
"orden": "3",
"antifona": "Lleva escrito sobre su manto y en su estandarte este nombre: «Rey de reyes y Señor de señores.» A él la gloria y el poder por los siglos de los siglos.",
"ref": "Cántico¦Cf. Ap 19, 1-2. 5-7",
"tema": "Las bodas del Cordero",
"intro": "",
"parte": "",
"salmo": "Aleluya._La salvación y la gloria y el poder son de nuestro Dios._⟨ⱤAleluya.⟩_Porque sus juicios son verdaderos y justos._ⱤAleluya, ⟨aleluya⟩.§Aleluya._Alabad al Señor, sus siervos todos._⟨ⱤAleluya.⟩_Los que le teméis, pequeños y grandes._ⱤAleluya, ⟨aleluya⟩.§Aleluya._Porque reina el Señor, nuestro Dios, dueño de todo._⟨ⱤAleluya.⟩_Alegrémonos y gocemos y démosle gracias._ⱤAleluya, ⟨aleluya⟩.§Aleluya._Llegó la boda del Cordero._⟨ⱤAleluya.⟩_Su esposa se ha embellecido._ⱤAleluya, ⟨aleluya⟩."
}
]},
"lecturaBreve": {
"ref": "1Co 15, 25-28",
"texto": "Cristo debe reinar hasta poner todos sus enemigos bajo sus pies. El último enemigo aniquilado será la muerte. Porque Dios ha sometido todas las cosas bajo sus pies. Mas cuando él dice que «todo está sometido», es evidente que se excluye a aquel que ha sometido a él todas las cosas. Cuando hayan sido sometidas a él todas las cosas, entonces también el Hijo se someterá a aquel que ha sometido a él todas las cosas, para que Dios sea todo en todo.",
"responsorio": "Tu trono, Señor, permanece para siempre.|Tu cetro real es cetro de rectitud.|Permanece para siempre.|Gloria al Padre, y al Hijo, y al Espíritu Santo.",
"forma": 6001230
},
"magnificat": {
"antifona": "«Me ha sido dado todo poder en el cielo y en la tierra», dice el Señor.",
"texto":""
},
"preces": {
"intro": "Hermanos, adoremos a Cristo Rey, el cual existe antes que todas las cosas, y en quien todas las cosas tienen su razón de ser. Elevemos a él nuestra voz, clamando:|Que venga tu reino, Señor.|Con la confianza que nos da el ser participantes de la realeza de Cristo y coherederos de su reino, elevemos nuestra voz al Padre celestial:",
"texto": "Cristo, nuestro rey y pastor, congrega a tus ovejas de todos los puntos de la tierra≠y apaciéntalas en verdes praderas de pastos abundantes.§Cristo, nuestro salvador y nuestro guía, reúne a todos los hombres dentro de tu pueblo santo: sana a los enfermos, busca a los extraviados, conserva a los fuertes,≠haz volver a los que se han alejado, congrega a los dispersos, alienta a los desanimados.§Juez eterno, cuando pongas tu reino en manos de tu Padre, colócanos a tu derecha≠y haz que poseamos el reino que nos ha sido preparado desde la creación del mundo.§Príncipe de la paz, quebranta las armas homicidas≠e infunde en todas las naciones el amor a la paz.§Heredero universal de todas las naciones, haz entrar a la humanidad con todos sus bienes al reino de tu Iglesia que tu Padre te ha dado,≠para que todos, unidos en el Espíritu Santo, te reconozcan como su cabeza.∞Cristo, primogénito de entre los muertos y primicia de los que duermen,≠admite a los fieles difuntos a la gloria de tu resurrección."
},
"oracion": "Dios todopoderoso y eterno,~que quisiste restaurar todas las cosas~por tu amado Hijo, Rey del universo,~te pedimos que la creación entera,~liberada de la esclavitud del pecado,~te sirva y te alabe eternamente.~Por nuestro Señor Jesucristo, tu Hijo,~que vive y reina contigo~en la unidad del Espíritu Santo,~y es Dios, por los siglos de los siglos."
}
}
}
To make it short, let's take some examples of this JSON.This part of JSON represents the table santo of the database, which has two columns: nombre, vida: "santo": {
"nombre": "",
"vida": ""
}
The class is like this:public class Santo {
private String nombre;
private String vida;
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getVida() {
return vida;
}
public void setVida(String vida) {
this.vida = vida;
}
}
Then you can see a node visperas much more complex with several primitive elements (chain, int, etc.) and other elements They're from another class.. If you look at the node, you can deduce that himno, salmodia, lecturaBreve, magnificat y preces are independent classes that in turn form part of visperaswhile oracion is a primitive (string) element that is also part of the eve.The class visperas is thus presented:public class Visperas {
private Himno himno;
private Salmodia salmodia;
private LecturaBreve lecturaBreve;
private Magnificat magnificat;
private Preces preces;
private String oracion;
public Himno getHimno() {
return himno;
}
public void setHimno(Himno himno) {
this.himno = himno;
}
public Salmodia getSalmodia() {
return salmodia;
}
public void setSalmodia(Salmodia salmodia) {
this.salmodia = salmodia;
}
public LecturaBreve getLecturaBreve() {
return lecturaBreve;
}
public void setLecturaBreve(LecturaBreve lecturaBreve) {
this.lecturaBreve = lecturaBreve;
}
public Magnificat getMagnificat() {
return magnificat;
}
public void setMagnificat(Magnificat magnificat) {
this.magnificat = magnificat;
}
public Preces getPreces() {
return preces;
}
public void setPreces(Preces preces) {
this.preces = preces;
}
public String getOracion() {
return oracion;
}
public void setOracion(String oracion) {
this.oracion = oracion;
}
}
If you want to keep analyzing, you can see inside the node salmodia There is still another node that is a class of its own, it is called: salmoCompleto.The class Salmodia is presented as follows:public class Salmodia {
public int tipo;
public List<SalmoCompleto> salmoCompleto;
/*Un getter super interesante*/
public SpannableStringBuilder getSalmoCompleto() {
for (SalmoCompleto s : salmoCompleto) {
/*
*Aquí doy formato a cada elemento del salmo:
*tema, texto, parte, etc
*y lo devuelvo formateado
*/
}
}
You can appreciate that salmocompleto is defined in Salmodia like a list of the kind SalmoCompleto: List<SalmoCompleto>The class SalmoCompleto is defined as this:public class SalmoCompleto {
private String orden;
private String antifona;
private String ref;
private String tema;
private String intro;
private String parte;
private String salmo;
//getter setter
}
This is very interesting and very useful. Because for example I need every psalm, be it 3, be 50, bring a specific format. To say something, that the member's letter color tema be red. Well, all that complete work I do in the method. getSalmoCompleto class Salmodiawhich is going through the array of psalms and forming. Get the referencesI show an example as I get each reference from the different nodes of my JSON: Gson gson = new Gson();
JSONObject jsonBreviario = jsonDatos.getJSONObject("breviario");
Breviario breviario = gson.fromJson(String.valueOf(jsonBreviario), Breviario.class);
MetaLiturgia meta = breviario.getMetaLiturgia();
Santo santo = breviario.getSanto();
Visperas visperas = breviario.getVisperas();
Himno himno = visperas.getHimno();
Salmodia salmodia = visperas.getSalmodia();
LecturaBreve lecturaBreve = visperas.getLecturaBreve();
Magnificat magnificat = visperas.getMagnificat();
Preces preces = visperas.getPreces();
For example, a process that could be complicated, as it is to get the full psalm with different formats, colors, and font sizes, becomes as simple as doing this: sb.append(salmodia.getSalmoCompleto());
the method does the rest.Have a clear approachAt first I was a little lost with GSON. My criterion was to build a JSON that respects my data model. I mean, if I have a board himnoJSON must have a node called himnoIf I have a board visperaswhich in turn uses elements from other tables, my JSON must have a node visperas and the necessary sub-nodes.From there we can deduce that the most important thing is structure your JSON well, respecting your data model. It would have been apparently easier not to create a node salmodia also with a sub-node salmoCompleto and put the salmos array directly into the main node. But it turns out there are other boards that also use salmodia, tables similar to visperasBut with another function. If I for (appears) ease get out salmoCompleto of the node salmodia and put it directly in the node visperasI do nothing but disrespect the design of data (a psalmComplete is a complete psalm), and I also compute life when I have to format each element of the psalm or when I have to use it from another class that also uses elements of the type SalmoCompleto.A very useful toolThere is a tool that helped me a lot to properly implement the data model. Once you have the JSON built according to your data model, you can paste it and generate the class in a correct way. It's about https://jsonutils.com , an online tool that generates classes from a JSON. The only criticism I can make is that it creates class members as publicI'll change them in my case. private to make the management of the members go through getter and setter.PD:I hope this answer will help you with your data model. If there is any doubt you can ask in comments.