How to read a json using Gson when the class contains Arraylist’s in JAVA

Asked

Viewed 199 times

1

Hi, I’m doing some college work and I’m having trouble faking a persistence. The idea is this, I have an Observable/Singleton class that does both the control of updating data from some lists and does the storage and import of this data from a json. Below follows my code:

/**
 * Singleton class. Representa uma estrutura simples de base de dados mantendo as
 * informações em um arquivo JSON no root da aplicação.
 */
public class Db extends Observable {

    // construtores
    private Db() {
        fileName = "db.json";
        assinantes = new ArrayList<>();
        mensagens = new ArrayList<>();
        regras = new ArrayList<>();
        conquistas = new ArrayList<>();
    }

    private Db(int i) throws IOException {
        fileName = "db.json";
        try {
            get();
        } catch (IOException e) {
            assinantes = new ArrayList<>();
            mensagens = new ArrayList<>();
            regras = new ArrayList<>();
            conquistas = new ArrayList<>();
            set();
        }
    }

    // implementação singleton
    private static Db instance;

    public static Db getInstance() throws IOException {
        if (instance == null) instance = new Db(0);
        return instance;
    }

    // implementação persistence
    protected String fileName;

    // getters & setters
    private ArrayList<AssinanteFree> assinantes;

    public ArrayList<AssinanteFree> getAssinantes() {
        return instance.assinantes;
    }

    public void setAssinantes(ArrayList<AssinanteFree> v) {
        assinantes = v;
        emit();
    }

    private ArrayList<Mensagem> mensagens;

    public ArrayList<Mensagem> getMensagens() {
        return instance.mensagens;
    }

    public void setMensagens(ArrayList<Mensagem> v) {
        mensagens = v;
        emit();
    }

    private ArrayList<Regra> regras;

    public ArrayList<Regra> getRegras() {
        return instance.regras;
    }

    private ArrayList<Conquista> conquistas;

    public ArrayList<Conquista> getConquistas() {
        return instance.conquistas;
    }

    // methods
    private void emit() {
        setChanged();
        notifyObservers();
    }

    private void get() throws IOException {
        try (FileReader reader = new FileReader(fileName)) {
            Gson gson = new Gson();
            instance = gson.fromJson(reader, Db.class);
        }
    }

    private void set() throws IOException {
        try (Writer writer = new FileWriter(fileName)) {
            Gson gson = new GsonBuilder().create();
            gson.toJson(this, writer);
        }
    }

}

My problem is this. I can pull a json file for this class, so much so that it populates the other fields that are not of the type ArrayList<T> but in these (which are the most important) I can’t pull... Below is the json file I’m using:

{
    "fileName": "db.json",
    "assinantes": [
        {
            "id": 1,
            "nome": "Leandro",
            "tipo": "Vip",
            "pontuacao": 0,
            "dataCriado": "2018-06-27 05:00:00"
        },
        {
            "id": 1,
            "nome": "André",
            "tipo": "Premium",
            "pontuacao": 0
        },
        {
            "id": 1,
            "nome": "Maria",
            "tipo": "Free"
        }
    ],
    "mensagens": [],
    "regras": [
        { "tipo": "Free", "limiteMsg": 50, "addPontos": 0 },
        { "tipo": "Premium", "limiteMsg": 75, "addPontos": 1 }, 
        { "tipo": "Vip", "limiteMsg": 100, "addPontos": 1.4 }

    ],
    "conquistas": [
        { "descricao": "Novato", "minimo": 0 },
        { "descricao": "Iniciante", "minimo": 1 },
        { "descricao": "Experiente", "minimo": 4 },
        { "descricao": "Sênior", "minimo": 10 },
        { "descricao": "Legendario", "minimo": 100 }
    ],
    "changed": false,
    "obs": []
}

How do I import Arraylist’s ?

  • This Json is just like that?

1 answer

1


It needs to be created the class that will carry this information, but, what I could realize that the array of subscribers does not have a standard and this causes the data to not be loaded causing an exception if the field dataCriado is configured as Date (that would be correct) but to get around this I made the example with the type String ai is loaded normally:

Classes:

Subscribers:

package Classes;
public class Assinantes {
    private int id;
    private String nome;
    private int pontuacao;
    private String dataCriado;    
    public int getId() {
        return id;
    }
    public String getNome() {
        return nome;
    }
    public int getPontuacao() {
        return pontuacao;
    }
    public String getDataCriado() {
        return dataCriado;
    }
    public void setId(int id) {
        this.id = id;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    public void setPontuacao(int pontuacao) {
        this.pontuacao = pontuacao;
    }
    public void setDataCriado(String dataCriado) {
        this.dataCriado = dataCriado;
    }    
}

Achievements:

package Classes;
public class Conquistas {
    private String descricao;
    private int minimo;    
    public String getDescricao() {
        return descricao;
    }
    public int getMinimo() {
        return minimo;
    }
    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }
    public void setMinimo(int minimo) {
        this.minimo = minimo;
    }    
}

Messages:

package Classes;
public class Mensagens {

}

Obs:

package Classes;
public class Obs {

}

Rules:

package Classes;
public class Regras {
    private String tipo;
    private String limiteMsg;
    private Double addPontos;    
    public String getTipo() {
        return tipo;
    }
    public String getLimiteMsg() {
        return limiteMsg;
    }
    public Double getAddPontos() {
        return addPontos;
    }
    public void setTipo(String tipo) {
        this.tipo = tipo;
    }
    public void setLimiteMsg(String limiteMsg) {
        this.limiteMsg = limiteMsg;
    }
    public void setAddPontos(Double addPontos) {
        this.addPontos = addPontos;
    }    
}

Root:

package Classes;
import java.util.ArrayList;
public class Root {
    private String fileName;
    private ArrayList<Regras> regras;
    private ArrayList<Assinantes> assinantes;
    private ArrayList<Conquistas> conquistas;
    private boolean changed;
    private ArrayList<Mensagens> mensagens;
    private ArrayList<Obs> obs; 
    public ArrayList<Regras> getRegras() {
        return regras;
    }
    public void setRegras(ArrayList<Regras> regras) {
        this.regras = regras;
    }
    public String getFileName() {
        return fileName;
    }
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
    public ArrayList<Assinantes> getAssinantes() {
        return assinantes;
    }
    public void setAssinantes(ArrayList<Assinantes> assinantes) {
        this.assinantes = assinantes;
    }
    public ArrayList<Conquistas> getConquistas() {
        return conquistas;
    }
    public void setConquistas(ArrayList<Conquistas> conquistas) {
        this.conquistas = conquistas;
    }
    public boolean isChanged() {
        return changed;
    }
    public void setChanged(boolean changed) {
        this.changed = changed;
    }
    public ArrayList<Mensagens> getMensagens() {
        return mensagens;
    }
    public ArrayList<Obs> getObs() {
        return obs;
    }
    public void setMensagens(ArrayList<Mensagens> mensagens) {
        this.mensagens = mensagens;
    }
    public void setObs(ArrayList<Obs> obs) {
        this.obs = obs;
    }
}

Basically these classes carry the json question using the library com.google.code.gson as follows:

Gson gson = new Gson();
BufferedReader br = new BufferedReader(new FileReader("C:\\db.json"));
Root obj = gson.fromJson(br, Root.class);

Observing: it would not be better to create only type Root in that class Db and not use everything within it, because then the class code can be used in other parts of your code, code reuse, etc.?

  • 1

    Got it. About putting in another class like you did Root, for this project is not necessary as it is only for study but I will do it anyway. Thank you

Browser other questions tagged

You are not signed in. Login or sign up in order to post.