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

Programmatisk cachning av PrimeFaces-diagram via OmniFaces Cache-komponent

I det här inlägget kommer du att se hur du kombinerar PrimeFaces och OmniFaces för att få cachebara diagram. För att hålla sakerna enkla kommer vi att använda ett PrimeFaces linjediagram. För den här typen av diagram kan vi använda -taggen på sidan och en enkel hanterad böna. Så på sidan kan vi ha:

 <p:chart id="someChartId" type="line"
         model="#{chartView.lineModel}"
         style="height:300px;width:600px;"/>

ChartView kan skrivas enligt nedan:

 @Named
@ViewScoped
public class ChartView implements Serializable {

 private LineChartModel lineModel;

 @PostConstruct
 public void init() {
  createLineModels();
 }

 private void createLineModels() {
  lineModel = initLinearModel();
  lineModel.setTitle("Linear Chart");
  lineModel.setLegendPosition("e");
  lineModel.setZoom(true);
  Axis yAxis = lineModel.getAxis(AxisType.Y);
  yAxis.setMin(0);
  yAxis.setMax(10);
 }

 private LineChartModel initLinearModel() {
  LineChartModel model = new LineChartModel();

  LineChartSeries series1 = new LineChartSeries();
  series1.setLabel("Series 1");

  Random rnd = new Random();

  series1.set(rnd.nextInt(10), rnd.nextInt(10));
  series1.set(rnd.nextInt(10), rnd.nextInt(10));
  series1.set(rnd.nextInt(10), rnd.nextInt(10));
  series1.set(rnd.nextInt(10), rnd.nextInt(10));
  series1.set(rnd.nextInt(10), rnd.nextInt(10));

  LineChartSeries series2 = new LineChartSeries();
  series2.setLabel("Series 2");
  series2.set(rnd.nextInt(10), rnd.nextInt(10));
  series2.set(rnd.nextInt(10), rnd.nextInt(10));
  series2.set(rnd.nextInt(10), rnd.nextInt(10));
  series2.set(rnd.nextInt(10), rnd.nextInt(10));

  model.addSeries(series1);
  model.addSeries(series2);

  return model;
 }

 public LineChartModel getLineModel() {
  return lineModel;
 }
}

Denna kod kommer att producera ett enkelt linjediagram som i figuren nedan:

Låt oss nu anta att det här diagrammet regelbundet uppdateras eller återskapas under programkörningen (vi kommer att simulera detta via slumpmässiga serievärden och en Refresh knapp). Varje gång detta händer kommer vi att förlora det aktuella diagrammet. Men det kan vara användbart att cache (som spara) några av dessa diagram, och ha möjlighet att ladda dem senare under den aktuella sessionen (för diagram som tillhör vissa användare)/applikation (för diagram som är gemensamma för alla användare).

För att utföra denna uppgift kan vi använda OmniFaces Cache-komponenten. I grund och botten är den här komponenten mycket väl beskriven i boken OmniFaces Showcase and Mastering OmniFaces, men huvudidéerna är:

  • Cache komponenten exponeras för JSF-sidaförfattare via
    <o:cache> tag.
  • Cache  inkapslar en cachningsmekanism på serversidan för uppmärkningen som produceras av Render Response-fasen.
  • Cache vidtar åtgärder i Render Response-fasen.
  • Den cachade uppmärkningen lagras under en nyckel som genereras av OmniFaces eller anger via det valfria nyckelattributet <o:cache> .
  • Cachning kan inaktiveras per begäran via det valfria attributet disabled flag <o:cache> .
  • En cachad post kan cachelagras igen via återställningsflaggaattributet för <o:cache> .
  • Som standard lagras cachad data i sessionsomfång (applikationsomfång stöds också).

Till exempel, från JSF-sidförfattarens perspektiv, kan vi indikera att vi vill cachelagra en del av markeringen under nyckeln foo , som nedan:

 <o:cache id="cacheId" key="foo" disabled="false" reset="true">      
 ... // the markup produced for this snippet of code will be cached
</o:cache>

Självklart är disabled attribut kan hoppas över i det här exemplet, eftersom det är dess implicita värde. Om key också hoppas över, då genererar OmniFaces en. Om reset  hoppas över, att markeringen inte kommer att cachas igen.

Eftersom vi vill ha möjligheten att bestämma vilka sjökort som är cachade och ladda/ta bort ett visst sjökort från cachen kan vi inte bara göra bara detta:

 <o:cache id="cacheId">      
 <p:chart id="someChartId" type="line"
          model="#{chartView.lineModel}"
          style="height:300px;width:600px;"/>                   
</o:cache>

I grund och botten kommer detta att cache det första diagrammet och, vid varje postback, kommer det att servera detta diagram från cachen.

Så en snabb strategi kommer att bestå i att jonglera med <o:cache> attribut programmatiskt. Som jag sa ovan, Cache vidtar åtgärder i Render Response-fasen. Det betyder att vi kan styra från vår
ChartView bean Cache komponent innan cachningen faktiskt sker. Mittpunkten i denna implementering kommer att bestå av nedanstående private metod som tillåter oss att programmässigt konfigurera Cache komponent:

 private void configureCache(String key, boolean disabled, boolean reset) {
 Cache cache = Components.findComponent("cacheId");
 cache.setDisabled(disabled);
 cache.setReset(reset);
 cache.setKey(key);
}

Nu kommer vi att lägga till ett av de användargränssnitt som behövs för att styra cachen. Först lägger vi till en knapp märkt
Uppdatera. Praktiskt taget kommer ett nytt diagram att genereras varje gång vi trycker på den här knappen (ny data). Detta är för att simulera sjökortsuppdateringen.

<h:commandButton action="#{chartView.redrawAction()}" value="Refresh"/>

redrawAction() säkerställer att det nya diagrammet inte cachelagras, så cachning är inaktiverat och nyckeln är inte relevant:

 public void redrawAction() {
 configureCache("none", true, false);
 createLineModels();
}

Vidare lägger vi till en knapp märkt, Save . När den här knappen trycks in cachelagras det aktuella diagrammet under en tangent av typen key_slumptal  (i verkliga fall kanske du vill tillåta användaren att ange nyckeln som diagramtitel). key kommer att exponeras för användaren i en lista som representerar de sparade diagrammen:

<h:commandButton action="#{chartView.saveChart()}" value="Save"/>

saveChart() metoden möjliggör cachning och genererar en ny nyckel. Nyckeln lagras i en lista:

 private List<String> keys;
...
public void saveChart() {
 String key = "key_" + new Random().nextInt(1000);
 configureCache(key, false, true);
 keys.add(key);
}

Därefter listar vi de cachade nycklarna och en knapp märkt, Load . Användaren kan välja en nyckel och klicka på
Ladda-knappen för att ladda ett cachelagrat diagram:

 <h:selectOneMenu value="#{chartView.selected}">
 <f:selectItem itemLabel="Select a chart ..." noSelectionOption="true"/>
 <f:selectItems value="#{chartView.keys}" var="t" itemLabel="#{t}" itemValue="#{t}"/>
</h:selectOneMenu>
   
<h:commandButton value="Load Chart" action="#{chartView.loadChart()}"
                 disabled="#{chartView.keys.size() eq 0}"/>

loadChart() är:

 public void loadChart() {
 if (selected != null) {
     configureCache(selected, false, false);
 }
}

Slutligen lägger vi till en knapp märkt, Delete , vilket tar bort det valda diagrammet från cachen:

 <h:commandButton value="Delete Chart" action="#{chartView.deleteChart()}"
                 disabled="#{chartView.keys.size() eq 0}"/> |

Och deleteChart() är:

 public void deleteChart() {
 if (selected != null) {
     CacheFactory.getCache(Faces.getContext(), "session").remove(selected);
     keys.remove(selected);
     configureCache("none", true, false);           
     resetLineModels();
 }
}

private void resetLineModels(){       
 lineModel.getSeries().clear();
}

Lägg märke till här hur vi programmässigt kan ta bort en post från cacheminnet med hjälp av CacheFactory .

Här är en suggestiv skärmdump:

  • Den fullständiga ansökan finns tillgänglig här.

Java-tagg