Riempire una DataTable da JSON in PrimeFaces

Riempire una DataTable da JSON in PrimeFaces

In un progetto didattico su PrimeFaces, mi sono imbattutto in un problema: riempire una DataTable da JSON invece cha direttamente da database.

Vediamo come fare.

Prima di tutto, creiamo una classe che incapsula i nostri dati JSON:

import java.io.Serializable;

public class Blog implements Serializable {

    private String titolo;
    private int count;

    public Blog(String titolo, int count) {
        this.titolo = titolo;
        this.count = count;
    }

    public String getTitolo() {
        return titolo;
    }

    public void setTitolo(String titolo) {
        this.titolo = titolo;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

}

Dove titolo e count sono due proprietà dei dati JSON.

Il passo successivo è creare una classe che raccoglie e interpreta i dati:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ApplicationScoped;
import org.primefaces.json.JSONArray;
import org.primefaces.json.JSONException;
import org.primefaces.json.JSONObject;

@ManagedBean(name = "blogService")
@ApplicationScoped
public class BlogService {

    public List getData() throws MalformedURLException, IOException, JSONException {
        String strUrl = "http://www.example.com/data.php";
        List blogList = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        URL url = new URL(strUrl);
        URLConnection urlConn = url.openConnection();
        try (InputStreamReader isr = new InputStreamReader(urlConn.getInputStream(), Charset.defaultCharset()); BufferedReader buf = new BufferedReader(isr)) {
            String line;
            while ((line = buf.readLine()) != null) {
                sb.append(line).append("n");
            }
        }
        JSONArray jsonArray = new JSONArray(sb.toString());
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject json = jsonArray.getJSONObject(i);
            blogList.add(new Blog(json.getString("titolo"), json.getInt("count")));
        }
        return blogList;
    }

}

I dati vengono presi da un web service; non importa dove sia (remoto o locale), ma è importante che siano strutturati in formato JSON corretto.

A questo punto creiamo una classe che verrà richiamata dalla pagina; in pratica rappresenta la view:

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import org.primefaces.json.JSONException;

@ManagedBean(name = "blogView")
@ViewScoped
public class BlogView implements Serializable {

    private List blogList = new ArrayList<>();

    @ManagedProperty("#{blogService}")
    private BlogService service;

    @PostConstruct
    public void init() {
        try {
            blogList = service.getData();
        } catch (IOException | JSONException ex) {
            
        }
    }

    public List getBlogList() {
        return blogList;
    }

    public void setBlogList(ArrayList blogList) {
        this.blogList = blogList;
    }

    public void setService(BlogService service) {
        this.service = service;
    }
}

Richiama i dati dal service precedente; e poi viene richiamata dalla pagina in questo modo:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>DT Json</title>
    </h:head>
    <h:body>
        <h:form>
            <p:dataTable var="blog" value="#{blogView.blogList}">
                <p:column headerText="Titolo" sortBy="#{blog.titolo}">
                    <h:outputText value="#{blog.titolo}" />
                </p:column>
                <p:column headerText="Counter" sortBy="#{blog.count}">
                    <h:outputText value="#{blog.count}" />
                </p:column>
            </p:dataTable>
        </h:form>
    </h:body>
</html>

Il componente DataTable richiama il ManagedBean creato in precedenza (l'ultimo).

Alla fine è abbastanza semplice; molti degli strumenti sono gli stessi che abbiamo visto in altri articoli (come URLConnection, JSONArray, e JSONObject).

Enjoy!