Performance issue while setting and getting parameter in jsf bean - jsf-2

i m using JSF2.0 and i m making one dataTable in that datatable i m getting the value from managed bean.And in managed bean in post construct annoted method i m calling my web service from another file.
Following is code for that
<h:dataTable
value="#{bean1.getList}" var="c" styleClass="order-table"
headerClass="order-table-header" width="100%"
rowClasses="order-table-odd-row,order-table-even-row" rows="8"
columnClasses="first,second">
<h:column>
<f:facet name="header">
<h:selectBooleanCheckbox></h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox value="#{c.id}"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<!-- <f:facet name="header"/> -->
<h:outputLabel value="From: "></h:outputLabel>
<h:outputLabel value="#{c.from}"></h:outputLabel>
<br></br>
<!-- -->
<h:outputLabel value="Sub: "></h:outputLabel>
<h:outputLabel value="#{c.sub}"/>
<h:commandLink immediate="true" action="#{bean2.doRead}" value="Read" id="Read"></h:commandLink>
</h:column>
<!-- Footer Setting -->
<f:facet name="footer">
</f:facet>
</h:dataTable>
My Bean1 class
#PostConstruct
public void prepareList(){
{
web service call
}
public List<InboxBean> getemailList(){
return list;
}
Now when i m clicking on commandlink which has id Read at that time my bean1 post construct taged property also called. That i dont want to perform. So,how to get out from this problem and i also want to set the subject value in bean2 setProperty. Thanks in advance

That can happen if the bean is put in request scope. Every single HTTP request will then reconstruct the bean. Put the bean in view or session scope instead.
E.g. in the view scope:
#ManagedBean
#ViewScoped
public class Bean {}
A view scoped bean lives as long as you're interacting with the same view by returning null or void in action methods.
Or in the session scope:
#ManagedBean
#SessionScoped
public class Bean {}
A session scoped bean lives as long as the established browser session. That is, from the very first HTTP request involving the bean until the client closes the entire browser instance or when the session expires on the server side (which defaults to 30 minutes).
For your particular case, a view scoped bean is most likely the best choice.
See also:
How to choose the right bean scope?

Related

Passing and using parameters between JSF includes

I've been trying to understand JSF templating and include attributes and passing parameters between components. In Mastering JavaServer Faces 2.2 by Anghel Leonard, I came across the following example of passing parameters, which I don't fully understand.
Given this bean:
#Named
#ViewScoped
public class TemplatesBean implements Serializable {
private String msgTopDefault="";
private String msgBottomDefault="";
private String msgCenterDefault="No center content ... press the below button!";
public void centerAction(){
this.msgCenterDefault="This is default content";
}
// Getters and setters
}
Parameters are passed to contentDefault.xhtml with:
<ui:insert name="content">
<ui:include src="/template/default/contentDefault.xhtml">
<ui:param name="templatesBeanName" value="#{templatesBean}"/>
<ui:param name="contentPropertyName" value="msgCenterDefault"/>
</ui:include>
</ui:insert>
Then, within contentDefault.xhtml the parameters are used as follows:
<ui:composition>
<h:outputText value="#{templatesBeanName[contentPropertyName]}"/>
<h:form>
<h:commandButton value="Center Button" action="#{templatesBeanName['centerAction']()}"/>
</h:form>
</ui:composition>
I've never used the square-bracket syntax before, but if a reference to templatesBean is being passed in, why not just use that to access the properties or invoke action methods? For example, the following code works for me too and seems simpler:
<h:form>
<h:commandButton value="Center Button" action="#{templatesBeanName.centerAction()}"/>
</h:form>
Recognising that the example in the book may be a contrived example to illustrate a point, are there use cases where the other syntax is appropriate?
I do not know or own the book, so I cannot investigate that way what they want to illustrate, but I can sort of deduce that by looking at the full example you posted, not just the part about the centerAction.
If you look at
<ui:insert name="content">
<ui:include src="/template/default/contentDefault.xhtml">
<ui:param name="templatesBeanName" value="#{templatesBean}"/>
<ui:param name="contentPropertyName" value="msgCenterDefault"/>
</ui:include>
</ui:insert>
you'll see that 2 params are passesd on, templatesBeanName and contentPropertyName
In
<ui:composition>
<h:outputText value="#{templatesBeanName[contentPropertyName]}"/>
<h:form>
<h:commandButton value="Center Button" action="#{templatesBeanName['centerAction']()}"/>
</h:form>
</ui:composition>
from which you just pointed to the line with action="#{templatesBeanName['centerAction']()}", a dynamic bean with a static value in suqare brackets made into a method by adding () as a postfix, you'll see another line of code above it
<h:outputText value="#{templatesBeanName[contentPropertyName]}"/>
What effectively is done here is to have a dynamic bean AND a dynamic property name being used.
So my conclusion is that with this example what they are trying to illustrate is that you are able to pass on a dynamic bean, and on that bean use either both static or dynamic methods and properties(static properties and dynamic methods not being in the example)

#SessionScoped bean instantiated over and over [duplicate]

This question already has an answer here:
#SessionScoped bean looses scope and gets recreated all the time, fields become null
(1 answer)
Closed 8 years ago.
Using PrimeFaces 5.10, JSF 2, and Wildfly, I am trying to get my xhtml page to interact with a single instance of a #SessionScoped bean with a PF poll component. Each time the poll calls the bean method, a new instance of the bean is created. I've tried #ViewScoped and #SessionScoped with no change in behavior. I've noticed other similar questions, but have not seen any with a solution I have been able to implement.
I know the println's are not a reliable way to show order of method calls, but i'm using them to merely demonstrate which methods are being called and it appears that the init() method gets called over and over, even though I have #PostConstruct, so it's new instantiations. I'm even printing out "this" and it's showing different hashes each time it prints.
It never gets through the if statement in refreshTweets() because the stopPolling field never gets set to false in the right context.
I've run into this problem before and have been able to work around it rather than solve it. If anyone has any ideas as to what I am doing wrong, please let me know.
Below is the relevant xhtml code:
<p:layoutUnit id="center" position="center" styleClass="dataBox">
<h:form id="TwitterFeed">
<p:panelGrid columns="2">
<p:outputLabel value="Twitter topic to query: " />
<p:inputText value="#{dataBean.tweetTopic}"/>
<p:outputLabel value="Number of Twitter Results: " />
<p:inputText value="#{dataBean.tweetCount}" />
<p:commandButton value="Submit" action="#{dataBean.toggleRenderTweets}" update="tweets"/>
<p:commandButton value="Polling" action="#{dataBean.togglePolling}" update="tweets"/>
</p:panelGrid>
<p:panel visible="#{dataBean.renderTweets}" id="tweets">
<p:panelGrid columns="1">
<p:dataTable id="twitterTable" value="#{dataBean.tweetList}" var="tweetStatus">
<p:columns value="#{dataBean.tweetColumns}" var="column" columnIndexVar="colIndex">
<f:facet name="header">
<h:outputText value="#{column.header}"/>
</f:facet>
<h:outputText value="#{tweetStatus[column.property]}"/>
</p:columns>
</p:dataTable>
<p:poll interval="10" listener="#{dataBean.refreshTweets}" update="twitterTable" widgetVar="tweetPoll" id="tweetPoll" autoStart="true"/>
</p:panelGrid>
</p:panel>
</h:form>
</p:layoutUnit>
The relevant bean code is below:
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.annotation.PostConstruct;
import java.io.Serializable;
#SessionScoped
#ManagedBean
public class DataBean implements Serializable {
private List<TwitterStatusModel> tweetList;
private boolean renderTweets;
private boolean stopPolling;
#PostConstruct
public void init() {
<<initialize fields>>
stopPolling = true;
System.out.println(this + " init()");
}
private void getTweets() {
<<this method sets the List above tweetList>>
}
public void refreshTweets() {
if (!stopPolling) {
<<Method never passes the if statement because stopPolling is set to true in init()
}
public void togglePolling() {
stopPolling = !(stopPolling);
System.out.println(this + "Toggling polling - now " + stopPolling);
}
You should use the correct imports of #SessionScoped etc.
With a #ManagedBean you need the javax.faces.bean.* ones not the javax.enterprise.context ones or javax.faces.view
See also Why are there different bean management annotations

jsf2 search bean request scope is not displaying results

Here is my code,
search.xhtml page
<h:form id="searchform">
<h:inputText id="deptId" value="#{searchBean.departmentId}"></h:inputText>
<h:inputText id="deptName" value="#{searchBean.deparmentName}"></h:inputText>
<h:commandButton value="Click to Search" action="#{searchBean.searchEmployees}">
</h:commandButton>
</h:form>
searchresults.xhtml page
<rich:dataTable value="#{searchBean.employeeList}" var="e" id="table">
<rich:column>
<f:facet name="header">
<h:outputText value="FNAME"/>
</f:facet>
<h:outputText value="#{e.fName}"/>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="LNAME"/>
</f:facet>
<h:outputText value="#{e.lName}"/>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="DEPARTMENT"/>
</f:facet>
<h:outputText value="#{e.dept}"/>
</rich:column>
</rich:dataTable>
In the managed bean
ManagedBean
#ManagedBean(name="searchBean")
#RequestScoped
public class SearchBean implements Serializable{
private String departmentId;
private String deparmentName;
private List<EmpBean> employeeList;
//....get/set 's
public String searchEmployees(){
employeeList = service.getEmployees(departmentId,deparmentName);
return "searchresults.xhtml";
}
Issue: searchresults page is is not displaying records though it fetched records from table
I'm able to achieve this using search bean as session scope but i want to use the scope as Requestscope, bec of performance.
Please suggest...!
The Problem
The reason you're not seeing the results is because you have an incorrect understanding of the #RequestScope and consequently, improbable expectations of the scope
searchEmployees executes during the INVOKE_APPLICATION phase, the second to the last phase of the JSF request processing lifecycle. By the time the user is redirected to searchResults.xhtml, the instance of your SearchBean that holds the search results has been destroyed and a brand new one created, resulting in an empty list.
This is the rule for every bean scope except the #SessionScoped: a navigation action will cause the old bean to be destroyed and a new one created. This is not to say that #SessionScoped should be your scope of choice (it's generally a terrible idea to back a page with a #SessionScoped bean).
The Solution
Use the FlashScope to temporarily stash the results just for display on the other page. For example
employeeList = service.getEmployees(departmentId,deparmentName);
Flash theFlashScope = FacesContext.getCurrentInstance().getExternalContext().getFlash();
theFlashScope.put("searchResults",employeeList);
return "searchresults.xhtml";
Then in searchResults.xhtml
<rich:dataTable value="#{flash.searchResults}" var="e" id="table">
Here, #{flash} is an implicit EL object; you don't have to do anything else.
EDIT: Based on your "answer", you should be aware that the Flash object keeps variables stored in it for only the first render of the page. Subsequent HTTP requests will clear the content of the flash object.
If you're interested in keeping the content of the flash object beyond the first render, you should use the Flash#keep:
<rich:dataTable value="#{flash.keep.searchResults}" var="e" id="table">
Further Reading
Max Katz's blog on the Flash object

how to set error message to p:message inside ui:repeat from backing bean

I have a form contains with inputText and message component.
I want to set the error message from the backing bean but keep fail to do it.
Below is my html code:
<h:form id="formId">
<h:panelGrid id="repeater" columns="2">
<h:outputText value="#{msg['label.appeal.case.reference.no']}" />
<ui:repeat id="uirepeater" value="#{beanPage.list}" var="value" varStatus="status">
<h:panelGrid columns="2">
<p:inputText id="refNo" value="#{beanPage.list[status.index]}" />
<p:message for="refNo" display="text" />
</h:panelGrid>
</ui:repeat>
</h:panelGrid>
<p:commandButton id="btmAdd" actionListener="#{beanPage.addRow}" value="Add" update="#form" />
<p:commandButton id="btmSubmit" actionListener="#{beanPage.submit}" value="Submit" update="#form" />
</h:form>
below is backing bean code:
public void submit() {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "test", "test");
FacesContext.getCurrentInstance().addMessage(":formId:uirepeater:refNo", msg);
FacesContext.getCurrentInstance().addMessage(":formId:uirepeater:0:refNo", msg);
}
This will not work with ui:repeat.
The actual ID of the inputText will not be "refNo" as you might think.
The < ui:repeat > will ensure the uniqueness of the generated component's client ID by prepending it with the row index. It just renders the same component several times, not creating new components in the tree.
You probably need to use c:forEach, which generates several components in the tree.
For more info see:
https://rogerkeays.com/jsf-c-foreach-vs-ui-repeat
How can I set id of a component/tag inside ui:repeat
Try this
I use primefaces 4.0, ViewScope, Ajax request.
With p:component obtain the ClientId of p:messages atributte for="someComponent" and pass this value to bean through p:remoteCommand, later you can set the message from bean with ClientId.
In some element add this
onclick="rc([{name:'index',value:#{item.index}},{name:'msg1',value:'#{p:component('someComponent')}'}])"
Create p:remoteCommand to set the id
<p:remoteCommand process="#this" name="rc" action="#{bean.someMethod}"/>
public void someMethod(){
FacesContext context = FacesContext.getCurrentInstance();
Map<String,String> params = context.getExternalContext().getRequestParameterMap();
int index=Integer.parseInt(params.get("index"));
this.msg[index]=params.get("msg1");
}
Now you can set messages from bean:
FacesContext.getCurrentInstance().addMessage(this.msg[x], new FacesMessage(FacesMessage.SEVERITY_ERROR,null,"someMessage"));

Primefaces commandButton inside dialog not firing backing bean's method

I've just started learning JSF and PrimeFaces, and as soon as I solve a problem (with your help), another one arises. I have a datatable showing some data about my application's users; in the last column, a commandButton invokes a dialog allowing the corresponding data to be edited. The dialog actually interacts with the backing bean, since the fields are correctly precompiled with the existing data, but the "Submit changes" commandButton doesn't fire the proper editUser() method!
I've searched everywhere for a solution to my problem, but none of the threads on the PrimeFaces forums nor any question here on Stack Overflow helped me: I tried all combinations of action, actionListener, inner <h:form>, outer <h:form>, even the dreaded nested <h:form>, but the underlying method is still not called.
Thank you all, people!
EDIT: I included some more xhtml. Just to be clear: in the datatable I'm implementing both single and multiple selection mechanisms. The single selection is performed by the editButton in the last column and triggers the editDialog that's giving me pain, while multiple selection is enabled by the checkboxes in the first column and is targeted by a commandButton at the bottom of the table that deletes all selected users; of course they store the selections in different fields in the backing bean (selectedUser and selectedUsers[], respectively).
xhtml file
<h:form id="tableForm">
<p:dataTable id="userList" var="user" value="#{userListBean.userList}"
selection="#{userListBean.selectedUsers}" rowKey="#{user.username}">
<!-- this is a checkbox column I use for multiple selection -->
<p:column selectionMode="multiple" style="width:2%"/>
<!-- other datatable columns -->
<!-- this is the button column that triggers the dialog -->
<p:column style="width:4%">
<p:commandButton id="editButton" update=":tableForm:editUserData"
oncomplete="PF('editDialog').show()" title="Edit" icon="ui-icon-pencil">
<f:setPropertyActionListener target="#{userListBean.selectedUser}"
value="#{user}" />
</p:commandButton>
</p:column>
</p:datatable>
<p:dialog id="editDlg" widgetVar="editDialog" header="Edit User"
showEffect="fade" hideEffect="fade" modal="true" dynamic="true">
<h:panelGrid columns="6" id="editUserData">
<p:outputLabel for="editUsername">Username:</p:outputLabel>
<p:inputText disabled="true" id="editUsername" value="#{userListBean.selectedUser.username}" />
<p:message for="editUsername" />
<!-- and other fields like that -->
</h:panelGrid>
<p:commandButton id="submitChanges" action="#{userListBean.editUser()}"
value="Submit changes" oncomplete="PF('editDialog').hide();" />
</p:dialog>
</h:form>
Backing bean
#ManagedBean(name="userListBean")
#ViewScoped
public class UserListBean {
private UserDTO selectedUser;
public UserListBean() {
}
//some methods...
public String editUser() {
System.out.println("------------------ EDIT TRIGGERED! -------------------");
System.out.println(selectedUser.getUsername());
//this stuff never gets printed, so the method is never called!
}
//getters and setters
}
Actually, the only thing didn't come to my mind turned out to be the one that worked.
I sorted out my issue by using THREE forms (as I mentioned in my question, I had already tried out all possible combinations of one and two forms, even nested ones), like this:
<h:form id="tableForm">
<!-- here lies the p:dataTable -->
</h:form>
<p:dialog>
<h:form id="dialogForm">
<!-- here lies the h:panelGrid with the editable fields -->
</h:form>
<h:form id="buttonForm">
<!-- and HERE goes the commandButton, alone -->
</h:form>
</p:dialog>
It looks like everyone solves this problem in ways that don't work for others :) .

Resources