ManagedBean functions not being called - jsf

I am trying to create a basic datatable which fetches the value from database and displays in the table format. However while I try to debug I see that managed bean functions are not being called. Below is the code
list.xhtml:
<h:body>
<h3>Expense list</h3>
<h:dataTable value="#{userMB.entries}" var="e" styleClass="table"
headerClass="table-header" rowClasses="table-odd-row,table-even-row">
<h:column>
<f:facet name="header">Date</f:facet>
#{e.date}
</h:column>
</h:dataTable>
</h:body>
UserMB.java
#ManagedBean
#SessionScoped
public class UserMB {
private List<Entry> entries;
#EJB(mappedName = "entryServices")
private EntryServices entryServices;
public UserMB() {
}
#PostConstruct
public void init() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context
.getExternalContext().getRequest();
HttpSession httpSession = request.getSession(false);
User user = (User) httpSession.getAttribute("user");
entries = new ArrayList<Entry>();
entries = entryServices.getEntryByUser(user);
}
public List<Entry> getEntries() {
return entries;
}
public void setEntries(List<Entry> entries) {
this.entries = entries;
}
public EntryServices getEntryServices() {
return entryServices;
}
public void setEntryServices(
EntryServices entryServices) {
this.entryServices = entryServices;
}
}

I don't see any error in the code or the facelet, sometimes I not choose the right package for the annotation that must be javax.faces.ManagedBean and javax.faces.SessionScoped otherwise the bean is never created.
In glassfish when I use a EJB in the ManagedBean it need to be serialized could you try this.
I hope this could help you.

This is my problem.
Change the imports and works:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

Related

JSF websocket update viewScope

I have a bean named sampleBean scoped by viewScope .
this bean load some data from database (MySQL) .
my problem is some records shared between users .
now maybe [USER A] delete that shared record and i want to update view of other users .
I can not change scope to ApplicationScope because all records shared to all users .
How can fix this problem ?
Note : I read this post but can not understand how can fix this problem .
Note : I use Liberty 18.0.0.4 by JavaEE 8 (webProfile)
I fixed problem by this simple code . (I shared this code for you)
public class Information {
private String name ;
private String family ;
// constructor
// Getter & Setter
// override equal and hashCode
}
This is a simple service . (I simulated database on this class)
#Stateless
public class InformationService {
private static final List<Information> db = new ArrayList<>();
#Inject
#Push(channel = "infoChannel")
PushContext push;
#PostConstruct
public void init() {
Information userA = new Information("John", "Vankate");
Information userB = new Information("Julius", "Sampao");
db.add(userA);
db.add(userB);
}
public void remove(Information info) {
db.remove(info);
push.send("deleteInfo");
}
public List<Information> findAll() {
return db;
}
}
and simple JaxRs resources :
#Path("/info")
#RequestScoped
public class InformationResources {
#EJB
private InformationService informationService;
#Path("/delete")
#POST
#Consumes("application/json")
public String send(Information information) {
informationService.remove(information);
return "Receive : " + information;
}
}
Now Start JSF :
#Named
#ViewScoped
public class InformationBean implements Serializable {
private Information info ;
private List<Information> informationList ;
#EJB
private InformationService informationService ;
#PostConstruct
public void init() {
informationList = informationService.findAll();
info = new Information() ;
}
public void deleteInformation() {
informationService.remove(info);
}
public Information getInfo() {
return info;
}
public void setInfo(Information info) {
this.info = info;
}
public List<Information> getInformationList() {
return informationList;
}
public void setInformationList(List<Information> informationList) {
this.informationList = informationList;
}
}
and xhtml :
<h:body>
<p:dataTable value="#{informationBean.informationList}" var="info" id="infoTable">
<p:column rowHeader="name">
<h:outputText value="#{info.name}"/>
</p:column>
<p:column rowHeader="family">
<h:outputText value="#{info.family}"/>
</p:column>
<p:column rowHeader="action">
<h:form>
<p:commandButton value="Delete" action="#{informationBean.deleteInformation}">
<f:setPropertyActionListener value="#{info}" target="#{informationBean.info}"/>
</p:commandButton>
</h:form>
</p:column>
</p:dataTable>
<hr/>
<f:websocket channel="infoChannel">
<p:ajax event="deleteInfo" update="infoTable"/>
</f:websocket>
</h:body>
I already thought , PushContext must implemented on JSF beans , Now I understand can implement that in service or business logic layer .
Now you can remove information from JaxRs (Rest API) and record removed from p:dataTable without refresh page .
Note : this example use #ViewScoped

Managed property between SessionScoped ManagedBeans

I have the following problem!
On one of my sites i have a button:
<h:commandButton value="IDA Analyzer Results" action="#{SelectionBean.monitoringLog()}"/>
The method it calls with some part of the bean:
#ManagedBean(name = "SelectionBean")
#SessionScoped
public class TableSelectionBean {
private List<String> analyzerLog = new ArrayList<String>();
public String monitoringLog() throws FileNotFoundException, IOException{
String fileName = "/opt/IDA2/Linux/bin/"+"filtered_"+selectionMonitoringData.get(0).getMonitoringName()+"_result.txt";
if(selectionMonitoringData.get(0).getIsExecuted())
{
BufferedReader br = new BufferedReader(new FileReader(fileName));
try {
String line;
while ((line=br.readLine()) != null) {
getAnalyzerLog().add(line);
}
} finally {
br.close();
System.out.println(getAnalyzerLog());
}
}
return "analyzerresult.xhtml";
}
After i click this button as you can see it navigates me to an other page:
<h:body>
<h:form>
<h:commandButton value="hi" action="#{AnalyzerBean.myMethod()}"></h:commandButton>
</h:form>
</h:body>
Here is the Bean:
#ManagedBean(name = "AnalyzerBean")
#SessionScoped
public class AnalyzerResultBean {
#ManagedProperty(value="#{SelectionBean.analyzerLog}")
private List<String> analyzerLog;
public void myMethod(){
System.out.print(analyzerLog);
}
/**
* #return the analyzerLog
*/
public List<String> getAnalyzerLog() {
return analyzerLog;
}
/**
* #param analyzerLog the analyzerLog to set
*/
public void setAnalyzerLog(List<String> analyzerLog) {
this.analyzerLog = analyzerLog;
}
So when I'm trying to use this Managed property it says:
The scope of the object referenced by expression #{SelectionBean.analyzerLog}, view, is shorter than the referring managed beans (AnalyzerBean) scope of session but as you can see both of the is Session Scoped. What could be the problem?
If you use JSF 2.x and you want to navigate analyzerresult.xhtml page return analyzerresult
public String monitoringLog() throws FileNotFoundException, IOException{
return "analyzerresult";
}
.xhtml extension is not needed.

h:selectManyListBox setter not setting all the values selected

<h:selectManyListbox id="sectorsListBox" size="2" multiple="multiple" value="#{Mybean.classificationSelectedItems}">
<f:selectItems id="sectors" value="#{Mybean.classificationSelectItems}"/>
</h:selectManyListbox>
Backing Bean has:
public class Mybean
{
private Map<String,String> classificationSelectItems = new LinkedHashMap<String,String>();
private List<String> classificationSelectedItems = new ArrayList<String>();
//getter and setter for both.
}
init()
{
classificationSelectItems.put("INS","Insurance")
classificationSelectItems.put("HLC","HealthCare")
}
The select many box gets initialized with these 2 values but the problem is only the last selected entry is getting stored in classificationSelectedItems. Why is that so ? And how do I get all the selected entries stored in the list of classificationSelectedItems ?
Adding FYI, the init method is class by Spring.
I have tested with an examle(reference:http://www.mkyong.com/jsf2/jsf-2-multiple-select-listbox-example/), good luck :)
Facelets:
<h:form id="form">
<h:selectManyListbox value="#{user.favFood1}" >
<f:selectItems value="#{user.favFood2Value}" />
</h:selectManyListbox>
<h:commandButton value="test"/>
</h:form>
Bean:
#ManagedBean(name = "user")
#ViewScoped
public class UserBean implements Serializable {
private static final long serialVersionUID = 1L;
public List<String> favFood1;
private Map<String, Object> food2Value;
public UserBean() {
favFood1 = new ArrayList<String>();
food2Value = new LinkedHashMap<String, Object>();
food2Value.put("Food2 - Fry Checken", "Fry Checken1"); //label, value
food2Value.put("Food2 - Tomyam Soup", "Tomyam Soup2");
food2Value.put("Food2 - Mixed Rice", "Mixed Rice3");
}
public List<String> getFavFood1() {
return favFood1;
}
public void setFavFood1(List<String> favFood1) {
this.favFood1 = favFood1;
}
public Map<String, Object> getFavFood2Value() {
return food2Value;
}
}
I noticed exactly this behaviour when I used a Collection in the setter method, like
public void setClassificationSelectedItems(Collection<String> in){
// store it somewhere
}
This setter is called during the restore phase but not during the update phase, so the previously set value will be set, but never the new one. If you use a List, it works as expected:
public void setClassificationSelectedItems(List<String> in){
// store it somewhere
}
Note that you will need to redeploy the application after such a change because the JSP needs to be recompiled but this isn’t done automatically.

Pass values between Managed Beans of different pages [duplicate]

This question already has answers here:
Creating master-detail pages for entities, how to link them and which bean scope to choose
(2 answers)
Closed 3 years ago.
I can't pass values between two managed beans of different pages.
I am implementing a search box JSF component in a Home page. I request some values and when the user hits search it goes to the search result page.
The search result page has a JSF component SEARCH RESUKTS which needs to access the selection in the managed bean which correspond to the search box from the home page.
I have tried using injection but it seams that the Managed BEan box is reintialized, showing the default value. I pick an interest from the search box, i.e. Cinema, then I click search which takes me to search result, I hope to see cinema but I see Sport the defualt value.
Please find the code below.
SEARCH RESULT MANAGED BEAN
import javax.el.ELContext;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
#ManagedBean
#ApplicationScoped
public class ExpSearchResultsMB {
/** Creates a new instance of ExpSearchResultsMB */
public ExpSearchResultsMB() {
}
#ManagedProperty(value="#{expSearchBoxMB.selectedValue}")
private String selectedValue; // +setter
#ManagedProperty(value="#{expSearchBoxMB.text}")
private String prova;
public String getProva() {
return prova;
}
public void setProva(String prova) {
this.prova = prova;
}
public String getSelectedValue() {
return selectedValue;
}
public void setSelectedValue(String selectedValue) {
this.selectedValue = selectedValue;
}
}
SEARCH BOX MANAGED BEAN
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedProperty;
#ManagedBean
#ApplicationScoped
public class ExpSearchBoxMB {
public Date date;
public List<String> interests=new ArrayList<String>();
public String selectedValue="Sport";
public String getSelectedValue() {
return selectedValue;
}
public void setSelectedValue(String selectedValue) {
this.selectedValue = selectedValue;
}
public List<String> getInterests() {
interests.add("Sport");
interests.add("Musin");
interests.add("Art");
interests.add("Thatre");
interests.add("Cinema");
return interests;
}
public void setInterests(List<String> interests) {
this.interests = interests;
}
I would appreciate any help.
Cheers
I would say debug and check if the correct value is set on selection change of interests.
If everythig is correct but still you see the incorrect results then try using the following code in ExpSearchResultsMB
FacesContext context = FacesContext.getCurrentInstance();
ExpSearchBoxMB expSearchBoxMBBean = (ExpSearchBoxMB) context.getApplication().evaluateExpressionGet(context, "#{expSearchBoxMB}", ExpSearchBoxMB.class);
expSearchBoxMBBean.getSelectedValue()
You can try this:
<h:panelGrid columns="2" >
<h:form>
<h:outputLabel for="prova" value="Prova: " />
<h:inputText binding="#{prova}" id="prova" />
<h:outputLabel for="interest" value="Interest: " />
<h:selectOneMenu binding="#{interest}" id="interest" >
<f:selectItems value="#{expSearchBoxMB.interests}" var="i"
itemLabel="#{i}" itemValue="#{i}" />
</h:selectOneMenu>
<h:button value="Search" outcome="Result">
<f:param name="prova" value="#{prova.value}" />
<f:param name="interest" value="#{interest.value}" />
</h:button>
</h:form>
</h:panelGrid>
Then in your ExpSearchResultsMB, you can get the value like this:
#ManagedBean
#ViewScoped
public class ExpSearchResultsMB {
private String interest;
private String prova;
private String statusMsg;
#PostConstruct
public void prepareResult() {
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
this.interest = request.getParameter("interest");
this.prova = request.getParameter("prova");
if (interest == null || prova == null) statusMsg = "Please provide all information";
else {
// Prepare result to show to the user
}
}
// Getters and Setters
}
If you use #RequestScoped for your ExpSearchResultsMB instead of #ViewScoped, you can use #ManagedProperty to get the submitted value as following:
#ManagedProperty(value="#{param.prova}"})
private String prova;
#ManagedProperty(value="#{param.interest}"})
private String interest;

#ManagedProperty - Inject one request scoped bean into another request scoped bean

I have this SearchBean:
#ManagedBean(name = "searchBean")
#RequestScoped
public class SearchBean implements Serializable
{
private String input = null;
// getter methods
public String getInput() {
return input;
}
// setter method
public void setInput(String input) {
this.input = input;
}
public String Submit() {
return null;
}
}
Can I inject it into another bean using #ManagedProperty. For example:
#ManagedBean(name = "bookBean")
#RequestScoped
public class BookBean implements Serializable
{
#ManagedProperty(value = "#{searchBean}")
private SearchBean searchBean;
#PostConstruct
public void init()
{
System.out.println("Value: " + searchBean.getInput());
}
public SearchBean getSearchBean() {
return searchBean;
}
public void setSearchBean(SearchBean searchBean) {
this.searchBean = searchBean;
}
}
And the Facelet (search.xhtml):
<h:form id="formSearch">
<h:commandButton value="Search" action="#{searchBean.Submit}" />
</h:form>
UPDATE: I have search.xhtml inserted into book.xhtml via a ui:insert component as follow:
<h:form id="formBooks">
<ui:insert name="search">
<ui:include src="/templates/common/search.xhtml"/>
</ui:insert>
</h:form>
The searchBean.getInput() method above should return a value as a result of a form's submission. Is the above method of injection possible?
I assume that SearchBean.input will be bound to an input field:
public class SearchBean implements Serializable {
private String input = null;
Something like this:
<h:inputText value="#{searchBean.input}" />
If so, then this will be null:
#PostConstruct
public void init()
{
System.out.println("Value: " + searchBean.getInput());
}
But, assuming a value has been set, it will not be null when this method is invoked:
public String Submit() {
return null;
}
Image from Richard Hightower's JSF for nonbelievers: The JSF application lifecycle.
The reason is due to how the JSF lifecycle works:
When #{searchBean...} is first resolved and found not to exist:
The bean is instantiated
Any dependency injections are performed (there aren't any in this case)
#PostConstruct method is invoked
The bean is placed into scope
Assuming the Apply Request Values and Validations phases succeed, SearchBean.setInput(String) is invoked in the Update Model Values phase
SearchBean.Submit() is invoked in the Invoke Application phase
This process is defined in the JSF specification.
Now, if SearchBean.input were injected directly from the parameter map, it would not be null during #PostConstruct:
#ManagedProperty(value = "#{param.someParamName}")
private String input;
However, there aren't any real advantages to this - you're skipping any input validation and you can't use SearchBean.input as a field binding because it will be overwritten in the Update Model Values phase.
The SearchBean.Submit() method is where your application logic for performing the search should go.

Resources