1

私はいくつかの JSF ページといくつかの管理 Bean を持っています。管理 Bean で、いくつかの odel ファイルを作成し、JSF で埋めようとします。しかし、値を設定しません。しかし、既存のモデルオブジェクトを使用するとうまくいきます。

ここに私のJSFコードがあります:

 <h:form>           
            <c:set var="patient" value="#{manageBean.patient}" />
            <p:panel id="panel" header="Patient" style="margin-bottom:10px;">  
                <h:panelGrid columns="2">  
                    <h:outputLabel value="First  name" />  
                    <p:inputText id="firstName" required="true" value="#{patient.firstName}" />  

                    <h:outputLabel value="Family  name" />  
                    <p:inputText id="familyName" required="true" value="#{patient.familyName}" />  

                    <h:outputLabel value="Sex"/>
                    <p:selectOneMenu id="sex" rendered="true" value="#{patient.sex}">
                        <f:selectItem itemLabel="Male" itemValue="male" />  
                        <f:selectItem itemLabel="Female" itemValue="female" />  
                    </p:selectOneMenu>

                    <h:outputLabel value="Birthday date" />  
                    <p:calendar value="#{patient.birthdayDate}" mode="inline" id="birthdayDate"/>  

                    <h:outputLabel value="Nationality"/>
                    <p:selectOneMenu id="nationality" rendered="true" value="#{patient.nationality}">
                        <f:selectItem itemLabel="Russian" itemValue="russian" />  
                        <f:selectItem itemLabel="Ukranian" itemValue="ukranian" />  
                    </p:selectOneMenu>

                    <h:outputLabel value="Adress" />  
                    <p:inputText id="adress" required="true" value="#{patient.adress}" />  

                    <h:outputLabel value="Phone number" />  
                    <p:inputMask id="phoneNumber" required="true" value="#{patient.phoneNumber}" mask="(999) 999-9999"/>
                </h:panelGrid>  
            </p:panel> 
            <p:commandButton value="Save" action="#{manageBean.save}" />  
        </h:form>   

そして私のManageBeanがあります:

@ManagedBean(name = "manageBean")
@SessionScoped
public class ManageBean implements Serializable {

    private Patient patient;
    private SessionFactory factory;

    public ManageBean() {
        factory = SessionFactoryWrap.getInstance();
    }

    public Patient getPatient() {
        patient = (Patient) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("patient");
        if (patient == null) {
            //patient = new Patient("", "", Sex.male, new Date(), Nationality.ukranian, "", "");
            patient = new Patient();
        }
        return patient;
    }

    public String save() {
        Session session = factory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.saveOrUpdate(patient);
            tx.commit();
        } catch (HibernateException ex) {
            if (tx != null) {
                tx.rollback();
            }
            ex.printStackTrace();
        } finally {
            session.close();
        }
        patient=null;
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("patient", null);
        return "go_home";

    }
}
4

2 に答える 2

3

変更してみてください:

<c:set var="patient" value="#{manageBean.patient}" />

に:

<ui:param name="patient" value="#{manageBean.patient}" />

このようにして、それをFacelets変数に入れると、後で get と set の両方で参照できるようになります。

次に、次のように、患者オブジェクトの初期化を@PostConstruct注釈付きメソッドに入れます。

@PostConstruct
public void init() {
    patient = new Patient(); // this will execute every tyme the bean is initialized
}

次に、患者のプロパティに通常のゲッターとセッター (カスタム コードなし) を使用します。

于 2013-01-27T01:37:59.683 に答える
1

問題を解決する別の方法は、パラメーターをまったく使用せず、UIInputコンポーネントを属性に直接バインドすることです。

<h:form>
    <p:panel id="panel" header="Patient" style="margin-bottom:10px;">
        <h:panelGrid columns="2">
            <h:outputLabel value="First  name" />
            <p:inputText id="firstName" required="true"
                value="#{manageBean.patient.firstName}" />
<!-- rest of JSF/Facelets code... -->
</h:form>

また、JSF のベスト プラクティスに従って、マネージド Bean を 2 つの方法で再定義できます (atm を見る限り)。

  • @SessionScopedajax リクエストを処理するために注釈を付ける必要はありません。また、コンストラクター (および@PostConstructメソッド) がセッションごとに 1 回だけ呼び出されることも意味します。この場合の最良のオプションは@ViewScoped注釈です。詳細:マネージド Bean スコープ

  • getter/setter メソッドにビジネス ロジックを含めないでください。これは#{managedBean.property}、JSF コード内で実行されるたびに実行されるためです。詳細: JSF が getter を複数回呼び出す理由。これを知っていれば、Bean コンストラクターまたは@PostConstructメソッドでセッション データを 1 回だけロードすることをお勧めします。

これで、マネージド Bean は次のようになります。

@ManagedBean(name = "manageBean")
@ViewScoped
public class ManageBean implements Serializable {

    private Patient patient;
    private SessionFactory factory;

    public ManageBean() {
    }

    @PostConstruct
    public void init() {
        //it would be better to initialize everything here
        factory = SessionFactoryWrap.getInstance();
        patient = (Patient)FacesContext.getCurrentInstance().getExternalContext().
            getSessionMap().get("patient");
        if (patient == null) {
            patient = new Patient();
        }
    }

    public Patient getPatient() {
        return patient;
    }

    public void setPatient(Patient patient) {
        this.patient = patient;
    }

    public String save() {
        Session session = factory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.saveOrUpdate(patient);
            tx.commit();
        } catch (HibernateException ex) {
            if (tx != null) {
                tx.rollback();
            }
            ex.printStackTrace();
            //in my opinion, it would be better to show a descriptive message
            //instead of returning to the `go_home` view in case of errors.
        } finally {
            session.close();
        }
        //clumsy code line, no need to have it at all
        //patient = null;
        //Don't set the parameter to null, instead remove it from the session map.
        FacesContext.getCurrentInstance().getExternalContext().
            getSessionMap().remove("patient");
        return "go_home";

    }
}
于 2013-01-27T18:16:38.347 に答える