ManagedBean method doesn't work in JSF - 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}.

Related

setPropertyActionListener not working after a action

I have a grid with a list of objects and I am trying to create a basic CRUD. Updates and deletes are going quite fine and without any problems, however, when I try to perform a edit on the selected object the setPropertyActionListener that I've set isn't performing as expected. I've searched on several threads but no success.
Here goes my code:
On my crud-aplicacoes.html I gotta a grid and this is the code of my button where I set my setPropertyActionListener and also my action which goes to action ="editar-aplicacao" that is another page. I'm getting my property aplicacaoSelecionada always null.
<p:commandButton icon="ui-icon-pencil"
title="#{msg['label.button.editar']}" action="editar-aplicacao"
actionListener="#{aplicacoesMB.editarAplicacao}">
<f:setPropertyActionListener
target="#{aplicacoesMB.aplicacaoSelecionada}" value="#{app}" />
</p:commandButton>
My managed bean:
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import org.primefaces.model.DualListModel;
import br.com.cnen.enums.SituacaoAplicacaoeEnum;
import br.com.cnen.vo.AplicacaoVO;
import br.com.cnen.vo.PerfilVO;
import br.com.cnen.web.facade.AplicacoesFacade;
#RequestScoped
#ManagedBean(name = "aplicacoesMB")
public class AplicacoesMB extends BeanAbstract {
private static final long serialVersionUID = 1L;
private List<AplicacaoVO> listaAplicacoes;
private AplicacaoVO aplicacaoSelecionada;
private PerfilVO perfilSelecionado;
private boolean edicaoExibicao;
#Inject
private AplicacoesFacade facadeAplicacao;
private List<PerfilVO> source;
private List<PerfilVO> target;
private DualListModel<PerfilVO> dualListPerfil;
#PostConstruct
public void carregarAplicacoes() {
listaAplicacoes = facadeAplicacao.listarTodos();
this.edicaoExibicao = false;
dualListPerfil = new DualListModel<PerfilVO>();
}
public List<PerfilVO> perfis() {
return facadeAplicacao.carregarComboPerfis();
}
public List<SituacaoAplicacaoeEnum> comboStatus() {
List<SituacaoAplicacaoeEnum> lista = new ArrayList<SituacaoAplicacaoeEnum>();
for (SituacaoAplicacaoeEnum current : SituacaoAplicacaoeEnum.values()) {
lista.add(current);
}
return lista;
}
public String editarAplicacao() {
this.edicaoExibicao = false;
pickList();
return "editar-aplicacao";
}
public String visualizarAplicacao() {
this.edicaoExibicao = true;
return "editar-aplicacao";
}
public void excluirAplicacao() {
facadeAplicacao.remover(this.aplicacaoSelecionada);
this.carregarAplicacoes();
this.addMensagem("A exclusão foi realizada com sucesso.", FacesMessage.SEVERITY_INFO);
}
public void bloquearAplicacao() {
this.aplicacaoSelecionada.setSituacao(SituacaoAplicacaoeEnum.BLOQUEADO);
facadeAplicacao.bloquear(this.aplicacaoSelecionada);
this.addMensagem("O bloqueio foi realizado com sucesso!", FacesMessage.SEVERITY_INFO);
}
public void desbloquearAplicacao() {
this.aplicacaoSelecionada
.setSituacao(SituacaoAplicacaoeEnum.DESBLOQUEADO);
facadeAplicacao.desbloquear(this.aplicacaoSelecionada);
this.addMensagem("O desbloqueio com sucesso!", FacesMessage.SEVERITY_INFO);
}
public void alterarAplicacao(){
facadeAplicacao.alterar(aplicacaoSelecionada);
this.addMensagem("O atualização foi realizada com sucesso!", FacesMessage.SEVERITY_INFO);
}
public void addPerfil(){
}
public void pickList(){
source = facadeAplicacao.carregarComboPerfis();
target = new ArrayList<PerfilVO>();
if(aplicacaoSelecionada!=null)
target = aplicacaoSelecionada.getListaPerfis();
dualListPerfil = new DualListModel<PerfilVO>(source, target);
}
/**
*
* Getts and setters
*
*/
public List<AplicacaoVO> getListaAplicacoes() {
return listaAplicacoes;
}
public AplicacaoVO getAplicacaoSelecionada() {
return aplicacaoSelecionada;
}
public void setAplicacaoSelecionada(AplicacaoVO aplicacaoSelecionada) {
this.aplicacaoSelecionada = aplicacaoSelecionada;
System.out.println("-> "+ aplicacaoSelecionada.getAplicaoId());
}
public PerfilVO getPerfilSelecionado() {
return perfilSelecionado;
}
public void setPerfilSelecionado(PerfilVO perfilSelecionado) {
this.perfilSelecionado = perfilSelecionado;
}
public boolean isEdicaoExibicao() {
return edicaoExibicao;
}
public List<PerfilVO> getSource() {
return source;
}
public void setSource(List<PerfilVO> source) {
this.source = source;
}
public List<PerfilVO> getTarget() {
return target;
}
public void setTarget(List<PerfilVO> target) {
this.target = target;
}
public DualListModel<PerfilVO> getDualListPerfil() {
return dualListPerfil;
}
public void setDualListPerfil(DualListModel<PerfilVO> dualListPerfil) {
this.dualListPerfil = dualListPerfil;
}
}
On my editarAplicacao() I can't access the property because it is always going null. Any thoughts on this issue?
Your concrete problem is caused by (ab)using actionListener instead of action to perform a business action. All actionListeners are invoked in the very same order as they have been attached on the component and then finally the action is invoked.
In other words, the <f:setPropertyActionListener> is in your particular case invoked after #{aplicacoesMB.editarAplicacao}, which totally explains the symptom you're seeing of the property not being set.
Fix actionListener to be action.
action="#{aplicacoesMB.editarAplicacao}"
Additionally, you can also get rid of <f:propertyActionListener> altogether and pass the property as action method argument.
action="#{aplicacoesMB.editarAplicacao(app)}"
with
public String editarAplicacao(AplicacaoVO aplicacaoSelecionada) {
// ...
}
See also:
Differences between action and actionListener
How can I pass selected row to commandLink inside dataTable?
You can replace
<f:setPropertyActionListener
target="#{aplicacoesMB.aplicacaoSelecionada}" value="#{app}" />
with
<f:attribute name="aplicacao" value="#{app}"></f:attribute>
and in your actionListenerMethod getting the attribute :
this.aplicacaoSelecionada = ((AplicacaoVO) event.getComponent().getAttributes().get("aplicacao"));

how to access one managedbean from another in 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.

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.

Resources