how to access one managedbean from another in jsf - jsf

I have two managedbean class(UserBean.java & HelloBean.java) and one index.xhthl class. In HelloBean.java class, I have used #ManagedProperty anotation for accessing the property of UserBean.java and I have a method within HelloBean.java class.
here, my classes:
UserBean.java
package com.bean;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name="ubean", eager=true)
#SessionScoped
public class UserBean {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
HelloBean.java
package com.bean;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
#ManagedBean(name="hellobean", eager=true)
#RequestScoped
public class HelloBean {
#ManagedProperty(value="#{ubean}")
private UserBean mbean;
private String username;
public String getUsername() {
if(mbean!=null){
username=mbean.getUsername();
}
return username;
}
public void setMbean(UserBean mbean) {
this.mbean = mbean;
}
public UserBean getMbean() {
return mbean;
}
public void showMsg(){
System.out.println("UserName :"+username);
}
}
And, index.xhtml
<body>
<h:form>
<h:inputText id="username" value="#{ubean.username}"></h:inputText>
<h:commandButton value="submit" action="#{hellobean.showMsg}"></h:commandButton>
</h:form>
</body>
I want to invoke the showMsg() method from index.xhtml class. The method is fired by clicking commandButton, but it always returns null instead of inputText value. What's the problem in my codes. Someone, helps...
Thanks in advance..

Here username is the property of UserBean.java class. As a result, you must have to call the username variable through a object of the parent(UserBean.java) class.So, try it, mbean.getUsername() instead of only username.

Related

ManagedBean method doesn't work in JSF

I have written two managedbean classes named Message and HelloWorld. They are as follow :
Message.java :
package com.bean;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "message", eager = true)
#RequestScoped
#SessionScoped
public class Message {
private String message = "Hello World!";
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
HelloWorld.java
package com.bean;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "helloWorld")
#RequestScoped
#SessionScoped
public class HelloWorld {
#ManagedProperty(value="#{message}")
private Message messageBean;
private String msg;
public HelloWorld() {
System.out.println("HelloWorld started!");
}
public void setMessage(String message) {
this.msg = message;
}
public String getMessage() {
if(messageBean != null){
msg = messageBean.getMessage();
}
return msg;
}
public void setMessageBean(Message message) {
this.messageBean = message;
}
public void showMsg(){
// String str="I am a demo string!";
System.out.println(msg +" I am from showMsg()");
}
}
And, my index.xhtml here:
<body>
#{helloWorld.message}
<h:form>
<h:commandButton value="Show Msg" action="#{helloworld.showMsg}"/>
</h:form>
</body>
#{helloWorld.message} prints the message perfectly. But the <h:commandButton> does not invoke the methodshowMsg()`. What's the problem?
You have used action="#{helloworld.showMsg}" with lowercase w for world. EL is case sensitive. Change to action="#{helloWorld.showMsg}".
Also, what you have been told in the comments, you can't use both #RequestScoped and #SessionScoped, pick one. And, action attribute should resolve to String (showMsg() returns void), it is used to perform navigation. If you just want something done, without navigation, use actionListener instead.
A ManagedBean annotation doesn't work, if someone accidentally uses a different import, for example javax.annotation.ManagedBean. It must be javax.faces.bean.ManagedBean.
EL is case sensitive in jsf. You have used action="#{helloworld.showMsg} with lowercase w and you declare #ManagedBean(name="helloWorld") with uppercase W. Try it, action="#{helloWorld.showMsg}.

Target Unreachable, 'null' returned null in JSF2

I am quite new to JSF and I have this problem. I was reading some posts about that but I could found answer( or I didnt understood one...).
I have following user bean:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name="user")
#SessionScoped
public class User implements Serializable {
private String login;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
}
and login bean:
#ManagedBean(name="login")
#SessionScoped
public class Login implements Serializable{
private static final long serialVersionUID = 1L;
#ManagedProperty("#{user}")
private User user;
#PostConstruct
public void init() {
System.out.println("Init called");
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
And my view looks like this:
<h:inputText id="login" value="#{login.user.login}" required="true"/>
<h:commandButton value="Login" action="#{login.user.login}"/><br/>
I want access to user fields in few classess and this how I am trying to achieve this. Unfortunately I keep got this error.
I have found some information that I need beans.xml. Is that true? Where can I find sample? I am using JSF2.
Answer
My fault was that I choose same name for field and for login method. Because of that I was using login.login( before implementing User class) for geting login, and login.login as a action of commandButton. After I implemented User class I changed both login.login to login.user.login.
Thanks again for help.
You are binding a method User#login() to your CommandButton, which does not exist. There is only a property login (get/set).
You need a proper action method in your User bean:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name="user")
#SessionScoped
public class User implements Serializable {
private String login;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public void doLogin() {
// whatever you want to do here
}
}
and bind to the doLogin() method:
<h:commandButton value="Login" action="#{login.user.doLogin}"/>
beans.xml is required to enable CDI, which you don't use here. You are using jsf managed beans. CDI is a more powerful alternative.

Why is an exception thrown when an #ManagedProperty is referenced?

I have a JSF web application with a view-scoped bean and a session-scoped bean. I'd like to modify the session bean's members from the view bean, and I followed this guide from a certain well-known JSF guy, but I can't seem to get it to work without a runtime exception. The reference to the managed session bean, "home" is null when referenced, similar to this question except I've already followed the advice of the accepted answer.
package brian.canadaShipping;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
#ManagedBean(name= "requestBean")
#ViewScoped
public class CpstcRequestBean implements Serializable {
#ManagedProperty(value="#{home}")
private CpstcHomeBean homeBean;
public CpstcHomeBean getHomeBean() {
return homeBean;
}
public void setHomeBean(CpstcHomeBean homeBean) {
this.homeBean = homeBean;
}
private static final long serialVersionUID = -5066913533772933899L;
public String testVar = "hello world";
private boolean displayOutput = false;
public boolean isDisplayOutput() {
return displayOutput;
}
public void setDisplayOutput(boolean displayOutput) {
this.displayOutput = displayOutput;
}
public String getTestVar() {
return testVar;
}
public void setTestVar(String testVar) {
this.testVar = testVar;
}
public CpstcRequestBean()
{
System.out.println("TEST: " + homeBean.toString());
System.out.println("Hello, ResuestBean!");
}
}
The first bit of my "home" bean is as follows:
#ManagedBean(name= "home")
#SessionScoped
public class CpstcHomeBean implements Serializable {
...
UPDATE: I've followed Jordan's suggestions and I have the following in my view-scoped bean:
#ManagedBean(name= "requestBean")
#ViewScoped
public class CpstcRequestBean implements Serializable {
#Inject #Named("home") CpstcHomeBean homeBean;
public CpstcHomeBean getHomeBean() {
return homeBean;
}
public void setHomeBean(CpstcHomeBean homeBean) {
this.homeBean = homeBean;
}
public CpstcRequestBean()
{
System.out.println("TEST: " + homeBean.toString());
System.out.println("Hello, ResuestBean!");
}
...
as well as this in my session-scoped bean:
#Named("home")
#SessionScoped
public class CpstcHomeBean implements Serializable {
...
yet my "home" bean reference is still null. Any ideas?
UPDATE 2: It turns out that you must use #Named in both classes, not just the injected class. My web app now loads but some elements are blank. In my console log, I see, "Target Unreachable, identifier 'home' resolved to null." I'm running on Tomcat 7, if that affects things. Any ideas?
You can either change your session bean's #ManagedBean to #Named and then just inject it into your view scoped bean OR you can reference the session bean as is like this:
FacesContext fc = FacesContext.getCurrentInstance()
private CpstcHomeBean homeBean = (CpstcHomeBean) fc.getApplication().evaluateExpressionGet(fc, "#{home}", CpstcHomeBean.class);

JSF injection with managed property, good pattern?

I'm quite new to JSF and not really "used" to the different thinking so I'm struggling on what (I assume) is basic.
Lets say I have a class User, which is a session bean.
Lets say I have a controller of 10000 objects, say Factory, that needs to be able to set some of them as "locked", in our case it means that the "locked" field does not become null anymore but reference a "LockedItem" object.
This is where I can't get things working : LockedItem, when you instanciate it, is supposed to reference the user currently logged in. How am I supposed to do that ?
I tried injection with #managedproperty, but it is null in LockedItem.constructor (which is normal I assume) then I tried in a #PostConstruct method, but that method is never called (why ? Even if I make it a managedbean... are the postconstruct methods only called when the object is created by the ".xhtml" ?)
Or should I use a "java se" trick, like making the User static ?
Code to clarify why is a #PostConstruct not called (the one of "Seat") :
.xhtml
<h:outputLabel id="user" value="Hello #{user.name}" />
<h:outputLabel id="car" value="you have #{car.brand}" />
User
package test;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class User implements Serializable {
private String name ;
public User()
{
name = "toto";
System.out.println("User constructor");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Car
package test;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
#ManagedBean
public class Car implements Serializable {
private String brand ;
private Seat seat ;
public Car()
{
brand = "audi" ;
seat = new Seat();
System.out.println("Car constructor") ;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
Seat
package test;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
#ManagedBean
public class Seat implements Serializable {
private int nb ;
private String userName ;
#ManagedProperty("#{user}")
private User user ;
public Seat()
{
nb = 4 ;
userName="na";
System.out.println("! Seat constructor ") ;
}
#PostConstruct
public void init()
{
System.out.println("!! Seat postconstruct : "+user.getName());
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getNb() {
return nb;
}
public void setNb(int nb) {
this.nb = nb;
}
}
Thanks !
The #PostConstruct is the right way.
It's not called if you instantiate the bean yourself using new operator (obviously). It's only called if JSF instantiates and manages the bean itself whenever it's referenced for the first time in EL context like so #{bean}. This indeed usually happens in the view side, but this can also happen in model/controller side by #ManagedProperty("#{bean}") or Application#evaluateExpressionGet().
You should absolutely not make the User static. It would be shared applicationwide, not sessionwide.
An alternative is to just pass the current User as constructor argument of LockedItem, or to invoke the initialization method yourself, for sure if that class does not represent a legit JSF backing bean at all.

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;

Resources