ViewScoped bean is recreated each ajax request using p:remoteCommand - jsf

I have a javascript function responsible to call 2 managed bean methods using <p:remoteCommand/> the problem is that in one method i have to generate a value and use it in the second method, but when I call to the second method the value is null and this is because the ManagedBean is recreated each request, here is my code:
javascriptFile.js
<script>
function executeProcess(){
method1();
method2();
}
</script>
myView.xhtml
<h:form>
<p:remoteCommand name="method1"
actionListener="#{controller.method1()}"
update="xComponent" />
<p:remoteCommand name="method2"
actionListener="#{controller.method2()}"
update="xComponent" />
</h:form>
Controller.java
#ManagedBean
#ViewScoped
public class SearchCarneStudent implements Serializable {
private String myValue;
public void method1(){
myValue="Hello";
}
public void method2(){
System.out.println(myValue); //<- This line is returning null because the bean is recreated each request
}
}
I hope you can help me
Thanks

Related

poll doesn't work with setted var

I want to use one html page with two ManagedBeans. Depending on the parameter in the URL, I want to set the bean name through JSTL variable. For example:
<c:set var="bean" value="#{webModule1}" scope="request" />
or
<c:set var="bean" value="#{webModule2}" scope="request" />
I have class which was use all this time, so for sure this works:
#ManagedBean(name = "webModule1")
#ViewScoped
public class WebModule1 implements Serializable {
protected WebModulesFormBean form;
#PostConstruct
public void init() {
if (!firstInit()){
this.form= new WebModulesFormBean();
}
//some code
}
public void process() {
if(this.form.isActive()){
//some code
}
}
}
And new one:
#ManagedBean(name = "webModule2")
#ViewScoped
public class WebModule2 extends WebModule1 {
public void process() {
if(this.form.isActive()){
//code with some changes
}
}
}
This solutions works with value attribute and form in not null, for example:
<p:treeTable value="#{bean.form.root}" var="node" id="modulesTree">
But I have problem with this piece of code:
<p:poll listener="#{bean.process()}" widgetVar="documentOutcome" autoStart="#{bean.form.start}" update="modulesTree" async="false"
interval="1" id="myPoll2" />
When listener is called, NullPointerException appears.
And this problem is with all p:polls (I have a few), so this is not a problem with method code.
Problem is that 'form' is null, although at the beginning variable 'form' is initialized and treeTable is shown at the page. So 'form' starts to be null when the listener is called.
Thanks!
I have a solution!
The problem was with:
<c:set var="bean" value="#{webModule1}" scope="request" />
scope="request" was not enough and in my understanding this scope meant that when poll was called, a new bean reference was created and form variable was null because it was not a firstInit().
scope="view" is the solution.
Thank you for comments!

Passing Values from page to other page JSF

I am beginner in java server faces (JSF), I need to pass the content of text input to second page to display it, the same applies for the second page: I want to pass radio buttons values to a third page. I searched and tried a lot without success.
For example I tried
<h:commandButton value="Next" action="#{myBean.execute(input_id.value)}"/>
Execute method is:
public void execute(String value) {
// ...
try{
FacesContext.getCurrentInstance().getExternalContext().dispatch("/Quizy.xhtml?faces-redirect=true");
}
catch(Exception e){
System.out.println("err");
}
}
Any suggestions?
Here are 4 other ways to pass a parameter value from JSF page to other page JSF :
1- Method expression (JSF 2.0)
2- f:param
3- f:attribute
4- f:setPropertyActionListener
1. Method expression
Since JSF 2.0, you are allow to pass parameter value in the method expression like this #{bean.method(param)}.
JSF page
<h:commandButton action="#{user.editAction(delete)}" />
ManagedBean
#ManagedBean(name="user")
#SessionScoped
public class UserBean{
public String editAction(String id) {
//id = "delete"
}
}
2- f:param
Pass parameter value via f:param tag and get it back via request parameter in backing bean.
JSF page
<h:commandButton action="#{user.editAction}">
<f:param name="action" value="delete" />
</h:commandButton>
ManagedBean
#ManagedBean(name="user")
#SessionScoped
public class UserBean{
public String editAction() {
Map<String,String> params =
FacesContext.getExternalContext().getRequestParameterMap();
String action = params.get("action");
//...
}
}
3. f:atribute
Pass parameter value via f:atribute tag and get it back via action listener in backing bean.
JSF page
<h:commandButton action="#{user.editAction}" actionListener="#{user.attrListener}">
<f:attribute name="action" value="delete" />
</h:commandButton>
ManagedBean
#ManagedBean(name="user")
#SessionScoped
public class UserBean{
String action;
//action listener event
public void attrListener(ActionEvent event){
action = (String)event.getComponent().getAttributes().get("action");
}
public String editAction() {
//...
}
}
4. f:setPropertyActionListener
Pass parameter value via f:setPropertyActionListener tag, it will set the value directly into your backing bean property.
JSF page
<h:commandButton action="#{user.editAction}" >
<f:setPropertyActionListener target="#{user.action}" value="delete" />
</h:commandButton>
ManagedBean
#ManagedBean(name="user")
#SessionScoped
public class UserBean{
public String action;
public void setAction(String action) {
this.action = action;
}
public String editAction() {
//now action property contains "delete"
}
}
There are several ways for doing this, but here is one of them.
You will need to save the inputText value into a property of your bean and both your h:inputText and your h:commanButton should be in the same h:form element
Here is a sample code
In your view
<h:form>
...
<h:inputText value={myBean.someValue} />
....
<h:commandButton value="Next" action="#{myBean.execute()}"/>
</h:form>
Your managed bean should be at least session scoped if you want your property (someValue) to be available in different pages. The content of the managed bean should look like this also:
private String someValue;
// Getter and setter for `someValue`
public String execute() {
// ...
return "/Quizy.xhtml?faces-redirect=true";
}
In the second page if you want to retrieve that value, just use #{myBean.someValue}
to have this done, you just need to set the Value of Your component here inputText or radioButton to a Property of your Managed bean or Cdi bean called on the page of course you won't forget to have getter and setter method for ur property in ur bean. Finally be sure that the scope of Ur bean allow it to be alive (with all its properties' value) across the session. Then, from ur end page you may call ur Managed bean or Cdi bean proprety as value of page components

How to share data between two #ViewScoped beans?

I am trying to pass id (long) from one.xhtml to another .xhtml.
Both the backing beans are #ViewScoped and I am trying to share long id between them.
I am getting error with <f:viewParam/>
com.sun.faces.mgbean.ManagedBeanCreationException: Unable to create
managed bean saleOrder. The following problems were found:
- The scope of the object referenced by expression #{param.foo}, request, is shorter than the referring managed beans (saleOrder) scope of view.
I am have following code.
#ManagedBean
public class InvoiceView{
private long number;
// setter getter.
}
#ManagedBean
#ViewScoped
public SearchInvoice{
private List<InvoiceView> views;
private InvoiceView selectedView; // this is coming from <p:dataTable>
}
#ManagedBean
#ViewScoped
public class SaleOrder {
#ManagedProperty("#{param.foo}")
private String number;
#PostConstruct
public void init(){
//sysout number;
}
}
I have following code in searchInvoice.xhtml file.
<!-- I have not desclared <f:metadata/> -->
<h:commandButton value="Place Sale Order"
action="#{searchInvoice.forwardToSaleOrder}" <!-- this return saleOrder.xhtml string -->
rendered="#{not empty searchInvoice.views}">
<f:viewParam name="foo" value="#{searchInvoice.selectedView.number}" />
</h:commandButton>
You can use <f:viewParam> (JSF 2) in saleOrder.xhtml, which works with view scoped beans.
Check out this article.

Button not submit PrimeFaces 3.5

i'm using jsf + primefaces 3.5. And my button isn't calling one method in my managed bean.
I have this xhtml:
<h:form>
<p:inputText id="name" value="#{userMB.userSelected.name}" />
<p:commandButton id="btnSave" value="Salvar" actionListener="#{userMB.save}"/>
</h:form>
And my managed bean is:
#ManagedBean
#SessionScoped
public class UsuarioMB implements Serializable{
User userSelected;
public void save(){
System.out.println(userSelected.getName());
//call my daos and persist in database
}
}
The most curious is that if i remove the , the method is called!
If i put a atribute in p:commandButton "imediate = true ", the method is called, BUT, the information (userSelected.name) is null !
Thanks very much :)
It failed because it threw a NullPointerException because you never initialized userSelected.
Add this to your bean:
#PostConstruct
public void init() {
userSelected = new User();
}
If you have paid attention to the server logs, you should have seen it. As to the complete absence of feedback about the exception in the webbrowser, whereas in normal synchronous (non-ajax) you would have seen a HTTP 500 error page, it's because you're sending an ajax request without apparently an ExceptionHandler configured.
That it works when you set immediate="true" on the button is simply because it will then bypass the processing of all input components which do not have immediate="true" set.
See also:
What is the correct way to deal with JSF 2.0 exceptions for AJAXified components?
You have not given a name to the managedbean UsuarioMB. As suche it will be named usuarioMB.
#ManagedBean – marks this bean to be a managed bean with the name
specified in name attribute. If the name attribute in #ManagedBean is
not specified, then the managed bean name will default to class name
portion of the fully qualified class name.
read more about it in this blog: http://mkblog.exadel.com/2009/08/learning-jsf2-managed-beans/
Secondly, if your code above is complete, you are lacking public getter and setter for userSelected.
Thirdly you are missing the ActionEvent as you have declared a parameterless actionlistener, see Differences between action and actionListener
In order to get you code working you will need to change your xhtml to
<h:form>
<p:inputText id="name" value="#{usuarioMB.userSelected.name}" />
<p:commandButton id="btnSave" value="Salvar" actionListener="#{usuarioMB.save}"/>
</h:form>
And your managed bean as follows
import javax.faces.event.ActionEvent;
// ...
#ManagedBean
#SessionScoped
public class UsuarioMB implements Serializable{
private User userSelected;
public void save(ActionEvent event){
System.out.println(userSelected.getName());
}
public User getUserSelected() {
return userSelected;
}
public void setUserSelected(User userSelected) {
this.userSelected = userSelected;
}
}

JSF. Call backing bean method on every page load [duplicate]

This question already has answers here:
Invoke JSF managed bean action on page load
(4 answers)
Closed 6 years ago.
here is my situation in short.
I have page with datatable and few buttons backed by bean. Bean should be initialized with some default properties. That properties can be changed depending on action.
I started with RequestScoped bean and #PostConstruct annotated method. but it seems that datatable works well only with View(Session)scoped. Now my setup look like this:
#ManagedBean
#ViewScoped
public class ProductsTableBean implements Serializable {
private LazyDataModel<Products> productsData;
#Inject
private ProductsFacade model;
public void onPageLoad() {
// here some defaults are set
// ...
System.err.println("onPageLoad called");
}
public void addRow() {
// andhere some defaults redefined
// ...
System.err.println("addRow called");
}
...
and snippet from jsf page:
<p:commandButton action="#{productsTableBean.addRow()}"
title="save"
update="#form" process="#form" >
</p:commandButton>
...
<f:metadata>
<f:event type="preRenderView" listener="#{productsTableBean.onPageLoad}"/>
</f:metadata>
And here is the main problem arise in calling order, i have following output:
onPageLoad called
addRow called
onPageLoad called <-- :(
But i want addRow to be the last action to be called, like this:
onPageLoad called
addRow called
Any simple solution here ?
Check this link :
http://www.mkyong.com/jsf2/jsf-2-prerenderviewevent-example/
You know that the event is call on every requests : ajax, validation fail .... You can check if it's new request like this:
public boolean isNewRequest() {
final FacesContext fc = FacesContext.getCurrentInstance();
final boolean getMethod = ((HttpServletRequest) fc.getExternalContext().getRequest()).getMethod().equals("GET");
final boolean ajaxRequest = fc.getPartialViewContext().isAjaxRequest();
final boolean validationFailed = fc.isValidationFailed();
return getMethod && !ajaxRequest && !validationFailed;
}
public void onPageLoad() {
// here some defaults are set
// ...
if (isNewRequest()) {...}
System.err.println("onPageLoad called");
}

Resources