如何在 ActionListener 中注入托管 属性
How can I inject a managed property in an ActionListener
我想在 ActionListener 方法中处理来自其他 bean 的数据,但它抛出 NullPointerException
,所以我尝试在带有 @PostConstruct
注释的 init() 方法中将 bean 的实例重新安全到下一个实例,但是它仍然抛出 NullPointerException
。我知道可以通过 FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(context, expression, expectedType);
获取 bean,但是可以通过 @ManagedProperty
获取 bean 吗?这是代码:
Login.java
package sklad;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
public class Login implements ActionListener{
private Osoba os;
@ManagedProperty(value="#{osoba}")
private Osoba osoba;
@PostConstruct
public void init(){
os = osoba;
}
@Override
public void processAction(ActionEvent a) throws AbortProcessingException {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage("zprava", new FacesMessage(os.getId().toString() + " " + os.getHeslo()));
}
public Osoba getOsoba() {
return osoba;
}
public void setOsoba(Osoba osoba) {
this.osoba = osoba;
}
public Osoba getOs() {
return os;
}
public void setOs(Osoba os) {
this.os = os;
}
}
Osoba.java
package sklad;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
@ManagedBean
@SessionScoped
public class Osoba{
private Integer id;
private String heslo;
public Osoba(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getHeslo() {
return heslo;
}
public void setHeslo(String heslo) {
this.heslo = heslo;
}
}
login.xhtml
<!DOCTYPE html>
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>title</title>
<link rel="stylesheet" type="text/css" href="../styles/login.css" />
</h:head>
<h:body>
<p:growl id="growl" showDetail="true" life="3000" />
<p:panel id="panel_login" header="Přihlášení" styleClass="panel">
<p:panelGrid styleClass="panelGrid">
<h:form>
<p:row>
<p:column>
<h:outputText value="ID: " />
</p:column>
<p:column>
<h:inputText id="id_login" value="${osoba.id}" />
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputText value="Heslo: " />
</p:column>
<p:column>
<h:inputSecret id="heslo_login" value="${osoba.heslo}" />
</p:column>
</p:row>
<p:row>
<p:column colspan="2">
<h:commandButton id="btn_login" value="Přihlásit">
<f:actionListener type="sklad.Login"/>
</h:commandButton>
</p:column>
</p:row>
</h:form>
</p:panelGrid>
</p:panel>
</h:body>
</html>
更传统的调用动作侦听器的方法是使用方法绑定,如下所示:
@ManagedBean
@RequestScoped
public class Login {
...
public void doLogin(ActionEvent event){
// handle action
}
}
然后在按钮中:
<h:commandButton id="btn_login" value="Přihlásit" actionListener="#{login.doLogin}"/>
这种方法的好处是将 Login
变成了一个 ManagedBean,这将使 JSF 处理其上的注释 - 这使得 @ManagedProperty
注释按预期工作。
我想在 ActionListener 方法中处理来自其他 bean 的数据,但它抛出 NullPointerException
,所以我尝试在带有 @PostConstruct
注释的 init() 方法中将 bean 的实例重新安全到下一个实例,但是它仍然抛出 NullPointerException
。我知道可以通过 FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(context, expression, expectedType);
获取 bean,但是可以通过 @ManagedProperty
获取 bean 吗?这是代码:
Login.java
package sklad;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
public class Login implements ActionListener{
private Osoba os;
@ManagedProperty(value="#{osoba}")
private Osoba osoba;
@PostConstruct
public void init(){
os = osoba;
}
@Override
public void processAction(ActionEvent a) throws AbortProcessingException {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage("zprava", new FacesMessage(os.getId().toString() + " " + os.getHeslo()));
}
public Osoba getOsoba() {
return osoba;
}
public void setOsoba(Osoba osoba) {
this.osoba = osoba;
}
public Osoba getOs() {
return os;
}
public void setOs(Osoba os) {
this.os = os;
}
}
Osoba.java
package sklad;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
@ManagedBean
@SessionScoped
public class Osoba{
private Integer id;
private String heslo;
public Osoba(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getHeslo() {
return heslo;
}
public void setHeslo(String heslo) {
this.heslo = heslo;
}
}
login.xhtml
<!DOCTYPE html>
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>title</title>
<link rel="stylesheet" type="text/css" href="../styles/login.css" />
</h:head>
<h:body>
<p:growl id="growl" showDetail="true" life="3000" />
<p:panel id="panel_login" header="Přihlášení" styleClass="panel">
<p:panelGrid styleClass="panelGrid">
<h:form>
<p:row>
<p:column>
<h:outputText value="ID: " />
</p:column>
<p:column>
<h:inputText id="id_login" value="${osoba.id}" />
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputText value="Heslo: " />
</p:column>
<p:column>
<h:inputSecret id="heslo_login" value="${osoba.heslo}" />
</p:column>
</p:row>
<p:row>
<p:column colspan="2">
<h:commandButton id="btn_login" value="Přihlásit">
<f:actionListener type="sklad.Login"/>
</h:commandButton>
</p:column>
</p:row>
</h:form>
</p:panelGrid>
</p:panel>
</h:body>
</html>
更传统的调用动作侦听器的方法是使用方法绑定,如下所示:
@ManagedBean
@RequestScoped
public class Login {
...
public void doLogin(ActionEvent event){
// handle action
}
}
然后在按钮中:
<h:commandButton id="btn_login" value="Přihlásit" actionListener="#{login.doLogin}"/>
这种方法的好处是将 Login
变成了一个 ManagedBean,这将使 JSF 处理其上的注释 - 这使得 @ManagedProperty
注释按预期工作。