如何在ActionListener

时间:2016-02-03 15:05:42

标签: jsf jsf-2 dependency-injection actionlistener managed-property

我想要来自其他bean的进程数据,在ActionListener方法中,但它抛出NullPointerException,所以我尝试使用@PostConstruct注释的init()方法中的下一个实例的bean的resafe实例,但它仍然抛出NullPointerException。我知道可以通过FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(context, expression, expectedType);获取bean,但有可能通过@ManagedProperty吗?这是代码:

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>

1 个答案:

答案 0 :(得分:1)

更传统的调用动作侦听器的方法是使用方法绑定,如下所示:

@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注释按预期工作。