Java >> Java Program >  >> Tag >> char

RESTful Charts med JAX-RS och PrimeFaces

Ofta är det användbart att använda ett diagram för att ge en visuell representation av dina data. PrimeFaces tillhandahåller kartlösningar som gör det enkelt att lägga till visuella representationer av din data i webb- och mobilapplikationer. Om vi ​​kopplar användningen av PrimeFaces diagramkomponenter med RESTful webbtjänstdata kan vi skapa anpassade diagram som skalas väl för både stationära och mobila enheter.

I det här inlägget kommer jag att uppdatera Java EE 7 Hands On Lab MoviePlex-applikationen för att tillhandahålla en instrumentpanel i vilken vi kan integrera PrimeFaces-diagramkomponenter. Vi skapar ett diagram i det här exemplet, men du kan använda det här inlägget för att hjälpa dig bygga ännu fler diagram på liknande sätt. Närmare bestämt kommer vi att använda en RESTful webbtjänst för att samla in information om biografkapacitet, och vi kommer att visa var och en av biografkapaciteterna med hjälp av ett PrimeFaces stapeldiagram.

Börja med att ladda ner Java EE 7 Hands On Lab-applikationslösningsarkivet om du inte redan har gjort det. Därifrån öppnar du den i NetBeans IDE. För att skapa det här inlägget använder jag NetBeans 8.0.2. När projektet har importerats till NetBeans, distribuera det till din applikationsserver (GlassFish 4.1 i mitt fall) genom att högerklicka på projektet och välja Kör. När distributionen är klar öppnar du teaterwebbtjänsten i en webbläsare genom att öppna följande URL:http://localhost:8080/ExploringJavaEE7/webresources/theater/. Webbtjänsten bör skapa en lista som liknar den i figur 1.

Figur 1:Theater Web Service XML

Vi kommer att använda data från denna webbtjänst för att mata vår instrumentpanelswidget. Låt oss först skapa backend-koden, och sedan kommer vi att ta itu med användargränssnittet. Skapa först ett nytt paket med namnet org.glassfish.movieplex7.jsf , genom att högerklicka på Källpaket och välja "Nytt..."-> "Javapaket". Skapa sedan en JSF Managed Bean-kontroller genom att högerklicka på det paketet och välja "Ny..."-> "JSF Managed Bean" och döpa den till DashboardController . Låt oss annotera kontrollenheten som @SessionScoped , och implementera sedan java.io.Serializable . I denna styrenhet kommer vi att hämta data och konstruera modellen för instrumentbrädan. Vi kommer först att fråga webbtjänsten med en JAX-RS-klient, och vi kommer att använda data för att fylla i listan med Theater objekt. Därför måste vi definiera följande fyra fält för att börja:

Client jaxRsClient;
// Typically not hard coded...store in a properties file or database
String baseUri = "http://localhost:8080/ExploringJavaEE7/webresources/theater/";
    
private List<Theater> theaterList;
private BarChartModel theaterCapacityModel;

Klienten är av typen javax.ws.rs.client.Client , och vi kommer att initiera fältet i klasskonstruktorn genom att anropa javax.ws.rs.client.ClientBuilder , enligt följande:

public DashboardController() {
    jaxRsClient = ClientBuilder.newClient();
}

Därefter måste vi skapa en metod för att ladda data, skapa och konfigurera modellen. I vår styrenhet, init() Metoden innehåller i princip en implementering av att delegera uppgifter till andra metoder. init() metodimplementering anropar två metoder:loadData() och createTheaterCapacityModel() .

public void init() {
    loadData();
  
    createTheaterCapacityModel();
}

Koden är skriven så att det blir lätt att lägga till fler widgets till vår instrumentpanel vid ett senare tillfälle, om så önskas. loadData() metod tillhandahåller implementeringen för att ladda data från vår webbtjänst till vår lokala lista.

private void loadData() {
       
    theaterList = jaxRsClient.target(baseUri)
            .request("application/xml")
            .get(new GenericType>() {
            }
            );
      
}

Om vi ​​hade fler widgets skulle vi också lägga till dataladdningskoden för dessa datamodeller i den här metoden. Därefter måste vi initiera org.primefaces.model.chart.BarChartModel som vi hade definierat, och ladda den med data från webbtjänsten. initTheaterCapacityModel() Metoden innehåller implementeringen för att skapa BarChartModel och fylla den med ett eller flera ChartSeries-objekt för att bygga data.

public BarChartModel initTheaterCapacityModel() {

    BarChartModel model = new BarChartModel();

    ChartSeries theaterCapacity = new ChartSeries();
    theaterCapacity.setLabel("Capacities");


    for (Theater theater : theaterList) {

        theaterCapacity.set(theater.getId(), theater.getCapacity());

    }
    model.addSeries(theaterCapacity);

    return model;
}

Som du kan se består den här modellen av en enda  org.primefaces.model.chart.ChartSeries objekt. Egentligen kan modellen innehålla mer än en enda ChartSeries objekt, och olika färgade staplar kommer att användas för att visa dessa data i diagrammet. I det här fallet lägger vi helt enkelt till teaterns ID och kapaciteten för varje Theater invända mot ChartSeries objekt, och sedan lägger vi till det i BarChartModel . createTheaterCapacityModel() metod  anropas inom vår init() metoden, och i den använder vi initTheaterCapacityModel() metod för att skapa org.primefaces.model.chart.BarChartModel , och konfigurera den därefter.

private void createTheaterCapacityModel() {
    theaterCapacityModel = initTheaterCapacityModel();

    theaterCapacityModel.setTitle("Theater Capacity");
    theaterCapacityModel.setLegendPosition("ne");
    theaterCapacityModel.setBarPadding(3);
    theaterCapacityModel.setShadow(false);

    Axis xAxis = theaterCapacityModel.getAxis(AxisType.X);
    xAxis.setLabel("Theater");

    Axis yAxis = theaterCapacityModel.getAxis(AxisType.Y);
    yAxis.setLabel("Capacity");
    yAxis.setMin(0);
    yAxis.setMax(200);

}

Som du kan se, inuti metoden initialiserar vi modellen genom att anropa initTheaterCapacityModel() , och sedan konfigurerar vi det via en serie "set"-metoder. Specifikt anger vi titeln, positionen och tillhandahåller några visuella konfigurationer. Ställ sedan in axeln genom att anropa modellens getAxis() metod och passerar X- och Y-axelns konstanter. Vi konfigurerar sedan varje axel efter vår smak genom att ställa in en etikett och min/max-värden för Y-axeln. Se de fullständiga källorna för klassen i slutet av detta inlägg.

Det gör det för serversidans kod, låt oss nu ta en titt på UI-koden som används för att visa diagramkomponenten. Börja med att skapa en ny XHTML-fil i roten av mappen Web Pages i ditt projekt genom att högerklicka och välja "New..."-> "XHTML..." , och namnge filen dashboard.xhtml . Källorna för dashboard.xhtml bör innehålla följande:

<html xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns="http://www.w3.org/1999/xhtml">
    <h:head>
     
     
        <title>Theater Dashboard</title>

    </h:head>
    <h:body>
        <f:event listener="#{dashboardController.initView}" type="preRenderView"/>
        <h:form id="theaterDash" prependid="false">
            <p:growl id="growl" showdetail="true"/>
            <p:layout fullpage="true">
                <p:layoutUnit position="center">
                   
                            <p:panel header="Capacity for Theaters" id="theater_capacity" style="border: 0px;">
                                <p:chart model="#{dashboardController.theaterCapacityModel}" style="border: 0px; height: 200px; width: 500px;" type="bar">
                            </p:chart></p:panel>
                         
                 
                </p:layoutUnit>
            </p:layout>

            <p:poll interval="60" listener="#{dashboardController.pollData}"/>

        </h:form>

    </h:body>
</html>

Ganska förenklat innehåller JSF-vyn en PrimeFaces-layout, inklusive en panel och ett diagram. Nära toppen av vyn används en f:event-tagg för att anropa lyssnarmetoden som är implementerad i klassen DashboardController, identified by initView() . För detta exempel,  p:chart taggen är där magin händer. Diagramtypen i det här fallet är inställd på "stapel", även om andra alternativ finns tillgängliga (besök http://www.primefaces.org/showcase). Modellen är inställd på #{dashboardController.theaterCapacityModel} , som vi definierade, fyllde i och konfigurerade inom controllerklassen. Vi tillhandahåller sedan en bredd och en höjd för att diagrammet ska visas snyggt. Om data ändras (jag vet att biografer inte ökar eller minskar i storlek ofta, men följ mig här), lade vi till en PrimeFaces-undersökningskomponent som anropar pollData( ) metod, som uppdaterar data regelbundet. I det här fallet kommer uppgifterna att uppdateras var 60:e sekund. När det är färdigt ska diagrammet se ut som i figur 2.

Figur 2:PrimeFaces stapeldiagram

Diagrammet är interaktivt och om du klickar på etiketten kommer staplarna att döljas. Detta är praktiskt om du har mer än en kategori (via ChartSeries). ). Du kan till och med inkludera en p:ajax taggen i diagramkomponenten och anropa en åtgärd när diagrammet klickas på...kanske kommer en dialogruta upp för att visa ytterligare data om objektet som klickas på. Det gör det...nu kan du skapa ännu fler diagram med PrimeFaces och RESTful webbtjänster. Jag föreslår att man bygger vidare på MoviePlex-applikationen för att se vilka andra möjligheter som finns. Fullständiga källor för DashboardController-klassen:

package org.glassfish.movieplex7.jsf;

import java.util.List;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.GenericType;
import org.glassfish.movieplex7.entities.Theater;

import org.primefaces.model.chart.Axis;
import org.primefaces.model.chart.AxisType;
import org.primefaces.model.chart.BarChartModel;
import org.primefaces.model.chart.ChartSeries;

/**
 *
 * @author Juneau
 */
@Named(value = "dashboardController")
@SessionScoped
public class DashboardController implements java.io.Serializable {
    
    Client jaxRsClient;
    // Typically not hard coded...store in a properties file or database
    String baseUri = "http://localhost:8080/ExploringJavaEE7/webresources/theater/";
    
    private List theaterList;
  
    private BarChartModel theaterCapacityModel;


    /**
     * Creates a new instance of FamisEquipPmChartController
     */
    public DashboardController() {
        jaxRsClient = ClientBuilder.newClient();
    }
    
    public void init() {
        loadData();

        createTheaterCapacityModel();
    }
    
    /**
     * Initializes the view on page render...if we wish to grab a reference
     * to a panel, etc.
     */
    public void initView(){
        UIViewRoot viewRoot =  FacesContext.getCurrentInstance().getViewRoot();
        // Do something
    }

    public void pollData() {
        System.out.println("polling data...");
        loadData();
    }

    /**
     * JAX-RS client to poll the data
     */
    private void loadData() {
       
        theaterList = jaxRsClient.target(baseUri)
                .request("application/xml")
                .get(new GenericType>() {
                }
                );
      
    }

    

    /**
     * Initialize the Bar Chart Model for Displaying PM Estimated Hours by Month
     *
     * @return
     */
    public BarChartModel initTheaterCapacityModel() {

        BarChartModel model = new BarChartModel();

        ChartSeries theaterCapacity = new ChartSeries();
        theaterCapacity.setLabel("Capacities");


        for (Theater theater : theaterList) {

            theaterCapacity.set(theater.getId(), theater.getCapacity());

        }
        model.addSeries(theaterCapacity);

        return model;
    }

   

 
    
    private void createTheaterCapacityModel() {
        theaterCapacityModel = initTheaterCapacityModel();

        theaterCapacityModel.setTitle("Theater Capacity");
        theaterCapacityModel.setLegendPosition("ne");
        theaterCapacityModel.setBarPadding(3);
        theaterCapacityModel.setShadow(false);

        Axis xAxis = theaterCapacityModel.getAxis(AxisType.X);
        xAxis.setLabel("Theater");

        Axis yAxis = theaterCapacityModel.getAxis(AxisType.Y);
        yAxis.setLabel("Capacity");
        yAxis.setMin(0);
        yAxis.setMax(200);

    }

    /**
     * @return the theaterCapacityModel
     */
    public BarChartModel getTheaterCapacityModel() {
        return theaterCapacityModel;
    }

    /**
     * @param theaterCapacityModel the theaterCapacityModel to set
     */
   public void setTheaterCapacityModel(BarChartModel theaterCapacityModel) {
        this.theaterCapacityModel = theaterCapacityModel;
    }
    
   
}

Java-tagg