How to read a json using Gson when the class contains ArrayList's in JAVA

1

Hello, I'm doing a college job and I'm having trouble simulating a persistence. The idea is this, I have an Observable / Singleton class that does both the data update control of some lists and does the storage and import of that data from a json. Here is 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 even populates the other fields that are not of type ArrayList<T> but in these (which are the ones that matter most) I can not pull ... Below is the json file that I am 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?

    
asked by anonymous 28.06.2018 / 01:40

1 answer

1

The class that will load this information needs to be created, but, as far as I can see, array of subscribers do not have a default and this causes data not to be loaded causing an exception if the dataCriado field % is set to Date (which would be correct) but, to bypass this I did the example with type String ai is normally loaded:

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 {

}

Note:

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

These classes basically load the json of the question using the library with .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);

Note: It would not be best to only create type Root in this class Db and not use everything inside it, because, class can be used in other parts of your code, reuse code, etc.?

    
28.06.2018 / 02:20