In my JSF web application, I've a news panel (news.xhtml) which contains multiple published news. News are loaded into p:datagrid. In each p:datagrid cell, I have a "Read More" button where user is redirected to a new browser tab (readNews.xhtml) to read all the details of the related news.
<p:dataGrid id="newsDataGrid" var="news" value="#{newsService.newsList}" columns="3" layout="grid"
rows="6" paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="6,12,16"
paginatorPosition="bottom" lazy="true">
<h:panelGrid columns="1" style="width:100%">
<h:outputText value="#{news.title}" styleClass="newsTitle" />
<h:outputText value="#{news.publishDate}" styleClass="newsDate">
<f:convertDateTime pattern="dd/MM/yyyy hh:mm" />
</h:outputText>
<p:outputLabel value="#{news.subContent}" escape="false" style="font-style: italic;"/>
<p:commandButton value="Read More" onclick="target='_blank'" action="#{newsService.action(news.id)}" ajax="false" />
</h:panelGrid>
Since there are multiple news in news panel, the selected news has to be loaded in different browser tabs. When redirecting to new tabs, I am generating a UUID and appending it to the URL as shown below:
public void action(Long id) throws IOException {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
String key = UUID.randomUUID().toString();
externalContext.getSessionMap().put(key, id);
externalContext.redirect("readNews.xhtml?key=" + key);
}
When the the new redirected tab (readNews.xhtml) is loaded, I am retrieving the selected news data from the getter method of selectedNewsData field as below:
public News getSelectedNewsData() {
HttpServletRequest origRequest = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
String key = (String)origRequest.getParameter("key");
if(StringUtils.isNotBlank(key)) {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
Long newsId = (Long) externalContext.getSessionMap().get(key);
if(newsId != null) {
selectedNewsData = newsDAO.getNewsById(newsId);
}
}
return selectedNewsData;
}
My scenario works fine. All the selected news in different tabs are loaded independently.
However, my main problem arises here: the business logic rests in the getter method. In each call I have to retrieve the desired data from the database. As you know, In JSF request-response cycle, the getter method is called multiple times and this cause performance problem in my application.
Is there a way to retrieve each selected news data for once when the new tab is laoded and move business logic from getter method?