How to share data between two #ViewScoped beans? - jsf

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.

Related

ViewScoped bean is recreated each ajax request using p:remoteCommand

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

javax.el.PropertyNotFoundException: Target Unreachable, 'BracketSuffix' returned null

I am trying to insert multiple IPs in a List<String> using a simple example. But I am getting following error.
javax.el.PropertyNotFoundException: Target Unreachable, 'BracketSuffix' returned null
Here is my JSF 2.2 page:
<h:form id="form">
<ui:repeat value="#{exampleBean.ipAddresses}" var="s"
varStatus="status">
<h:inputText value="#{exampleBean.ipAddresses[status.index]}" />
</ui:repeat>
<h:inputText value="#{exampleBean.newIp}" />
<h:commandButton value="Add" action="#{exampleBean.add}" />
<h:commandButton value="Save" action="#{exampleBean.save}" />
</h:form>
And here is my backing bean:
#ManagedBean
#ViewScoped
public class ExampleBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> ipAddresses;
private String newIp;
#PostConstruct
public void init() {
ipAddresses= new ArrayList<String>();
}
public String save() {
System.out.println(ipAddresses.toString());
return null;
}
public void add() {
ipAddresses.add(newIp);
newIp = null;
}
public List<String> getIpAddresses() {
return ipAddresses;
}
public String getNewIp() {
return newIp;
}
public void setNewIp(String newIp) {
this.newIp = newIp;
}
}
How is this caused and how can I solve it?
javax.el.PropertyNotFoundException: Target Unreachable, 'BracketSuffix' returned null
The exception message is wrong. This is a bug in the EL implementation being used by the server. What it really meant here in your specific case is:
javax.el.PropertyNotFoundException: Target Unreachable, 'ipAddresses[status.index]' returned null
In other words, there's no such item in the array list. This suggests that the bean got recreated on form submit and therefore reinitializes everything to default. It thus behaves like a #RequestScoped one. Most likely you imported the wrong #ViewScoped annotation. For a #ManagedBean, you need to make sure that the #ViewScoped is imported from the very same javax.faces.bean package, and not thus the JSF 2.2-introduced javax.faces.view one which is specifically for CDI #Named beans.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
See also:
Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable
#ViewScoped bean recreated on every postback request when using JSF 2.2
Update: as per the comments, you're using WebSphere 8.5 which usually ships with an ancient MyFaces 2.0.x version. I reproduced your problem with MyFaces 2.0.5. Its <ui:repeat> failed to remember its view state for iteration status, that's why your construct still fails even though you're properly using a #ViewScoped bean. I could work around it by using <c:forEach> instead.
<c:forEach items="#{exampleBean.ipAddresses}" var="s" varStatus="status">
...
</c:forEach>
The alternate solution (apart from upgrading MyFaces to a more recent/decent version, obviously) would be to wrap the immutable String in a mutable javabean such as
public class IpAddress implements Serializable {
private String value;
// ...
}
so that you can use List<IpAddress> instead of List<String> and thus you don't need the varStatus anymore which triggered the MyFaces bug.
private List<IpAddress> ipAddresses;
private IpAddress newIp;
#PostConstruct
public void init() {
ipAddresses= new ArrayList<IpAddress>();
newIp = new IpAddress();
}
<ui:repeat value="#{exampleBean.ipAddresses}" var="ipAddress">
<h:inputText value="#{ipAddress.value}" />
</ui:repeat>
<h:inputText value="#{exampleBean.newIp.value}" />

Named Bean not injected into another named bean

I am trying to inject a named bean in another one.
When I try to access properties of the injected bean , it returns null which means that the injection fails.
Here is the first Bean:
#Named
#SessionScoped
public class FirstMBean {
String caracter;
..........
public String goToNext(){
String caracter=FacesContext.getCurrentInstance().getExternalContext().
getRequestParame‌​terMap().get("caracter"); this.caracter=caracter;
System.out.println("the selected caracteris"+ caracter);
return "/pages/next?faces-redirect=true"; }
}
The second named bean:
#Named
#SessionScoped
public class SecondMBean {
#Inject
FirstMBean firstMBean ;
String injectedCaracter ;
#PostConstruct
public void init() {
this.injectedCaracter = this.firstMBean.getCaracter();
System.out.println("injectedCaracter ----" + this.injectedCaracter);
}
In my .xhtml page :
<p:commandButton value="see caracter" action="#{firstMBean.goToNext}">
<f:param name="caracter" value="#{caracter}" />
</p:commandButton>
Please note that I am using tomcat server to which I added WELD to support CDI AND when I put the scope to ApplicationScoped, everything works fine.

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 #ManagedProperty doesn't work

On various places they said that you should use #ManagedProperty to get a request parameters. The problem is that I try to get the token from the request string but it somehow stays null all the time.
The link where the page is with called looks like this:
http://example.com/faces/Check.xhtml?token=EC-8AT450931P272300C&ID=VKEFF29XNGNJG
The bean:
#Named(value = "bean")
#RequestScoped
public class Bean implements Serializable {
#Inject
private AccountBean account;
#Inject
private Service web;
#ManagedProperty(value = "#{param.token}")
private String token;
#ManagedProperty(value = "#{param.ID}")
private String id;
#PostConstruct
public void init() {
System.out.println("token: " + token);
}
The page
<ui:define name="content">
<h:form>
<pou:commandButton action="#{bean.test()}" value="complete"/>
</h:form>
</ui:define>
And other things I tried:
Map<String, String> e = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
This doesn't contain the request parameters also. Same goes for all the facesContext things where you can get requests with.
Help will be appreciated.
P.S. I can't change anything behind the ? cause its called from a program not in my reach
Okay made it work.
#Inject to pass params to a CDI #Named bean via URL
This was the solution just needed to add a few more things to my site
<ui:define name="content">
<h:form>
<h:inputHidden value="#{bean.token}"/>
<h:inputHidden value="#{bean.id}"/>
<pou:commandButton action="#{bean.test()}" value="complete"/>
</h:form>
</ui:define>
And remove the #{param.xxx} part from the naming
#Inject #HttpParam
private String token;
#Inject #HttpParam(value = "ID")
private String id;

Resources