2

我有一个相当复杂的请求范围的 JSF 1.2 托管 bean,它具有各种方法和属性。一些属性映射到 URL 请求参数,以便它可以根据 URL 中的 id 属性填充实体对象。

我使用同一个托管 bean 来使用一个 jsf 页面为该实体创建一个新记录,另一个用于更新几个字段。在创建模式下,没有 url 参数,并且使用指定的操作方法提交表单只是执行它被告知的内容并执行该方法。

但是在更新模式下,从请求参数(在 URL 中)获取实体的 id,该参数使用从数据库中提取的实体数据完美地填充表单,提交按钮即不会调用同一托管 bean 上的操作方法,但是由于url中没有id,所以这次重新加载页面时url参数消失并且表单为空白,因此通过服务类方法引用相应数据以设置实体对象时使用的id属性为null。

那么,我将如何在这种更新模式下执行该方法呢?

听了一个建议,我还在更新表单中包含了隐藏字段,其中包含从 URL 获得的 id 参数的值,这似乎不起作用。

这是有问题的 JSF 页面中包含表单的代码片段:

<h:form id="ostOnayForm">
    <h:messages style="color:red" />

        <h:inputHidden value="#{oduncStokTalepBean.viewID}" />
        <h:inputHidden value="#{oduncStokTalepBean.adimID}" />

        <h:panelGrid id="oracleERP" columns="3"
                rendered="#{oduncStokTalepBean.aksiyon.faz==3}">
                Personel ödünç cari kodu:

        <h:inputText id="carikod" value="#{oduncStokTalepBean.oduncCariKod}"
                    required="true"
                    requiredMessage="Bu personelin 'ödünç cari kodu'nu girmelisiniz. (Eğer böyle bir kod tanımlı değilse, önce tanımı yapılmalıdır."
                    validatorMessage="Bu alana en fazla 25 karakter girebilirsiniz.">
                 <f:validateLength maximum="25" />
        </h:inputText>
        <h:message for="carikod" style="color:red" />
        </h:panelGrid>

        <h:panelGroup id="depocu1"
                rendered="#{oduncStokTalepBean.aksiyon.faz==2}">
            Personel ödünç cari kodu:
            <h:inputText value="#{oduncStokTalepBean.oduncCariKod}"
                    required="false"
                    validatorMessage="Bu alana en fazla 25 karakter girebilirsiniz.">
                <f:validateLength maximum="25" />
            </h:inputText>
        </h:panelGroup>

        <h:panelGroup id="depocu2"
                rendered="#{oduncStokTalepBean.aksiyon.faz==2}">
                <h:selectBooleanCheckbox value="#{oduncStokTalepBean.kargoyla}" />Ürün kargo firması ile teslim edilecek
        </h:panelGroup>

        <h:panelGrid columns="3"
                rendered="#{oduncStokTalepBean.onaylamaYetkisi}">
                Görüşler:
        <h:inputTextarea id="gorus" value="#{oduncStokTalepBean.gorus}"
                    required="true"
                    validatorMessage="Bu alana en fazla 255 karakter girebilirsiniz."
                    requiredMessage="Lütfen görüş de bildirin.">
        <f:validateLength maximum="255" />
        </h:inputTextarea>
        <h:message for="gorus" style="color:red" />

        <h:commandButton action="#{oduncStokTalepBean.vazgec}" value="Vazgeç" />

        <h:commandButton type="submit" action="#{oduncStokTalepBean.onayla}"
                    value="Onayla" rendered="#{oduncStokTalepBean.onaylamaYetkisi}" />
        <h:commandButton action="#{oduncStokTalepBean.reddet}"
                    value="Reddet"
                    onclick="return confirm('Bu formu reddetmek istediğinizden emin misiniz?')"
                    rendered="#{oduncStokTalepBean.onaylamaYetkisi}" />

        </h:panelGrid>
    </h:form>

支持bean:

public class OduncStokTalepBean extends SurecBean {

    private String oduncCariKod;
    private Boolean kargoyla;

    private OduncStokTalep oduncStokTalep = new OduncStokTalep("ost", "Ödünç Stok Talebi");
    private List<SelectItem> depoListesi = new ArrayList<SelectItem>();
    private OduncStokAdres osa = new OduncStokAdres();

    private OduncStokAdresJpaController osaServ = new OduncStokAdresJpaController();

    public OduncStokTalepBean() {
        super();
    }

    @PostConstruct
    public void initializeOST() {
        if (FacesUtil.getSessionAttribute("GO_Person_id") != null ) {
            GO_Person_id = Integer.valueOf((String) FacesUtil.getSessionAttribute("GO_Person_id"));
            if (viewID != null) {

                System.out.println("ostBean got viewID:"+viewID);
                this.oduncStokTalep = ostServ.findOduncStokTalep(viewID);
                this.editModu = true;
                this.oduncCariKod = this.oduncStokTalep.getPersonelOduncCariKodu();
                this.kargoyla = this.oduncStokTalep.getKargoylaTeslim();
                System.out.println("ost: "+oduncStokTalep.getId()+" * "+oduncStokTalep.toString());
                if (adimID != null) {
                    this.aksiyon = aServ.findAkisAdim(adimID);
                    this.setAksiyonModu(true);
                } else {
                    System.out.println("adimID was null, reading it from Surec...");
                    if (oduncStokTalep.getPendingAction()!=null) {
                        this.aksiyon = aServ.findAkisAdim(oduncStokTalep.getPendingAction());
                        System.out.println("Found :"+aksiyon.getId()+" "+aksiyon.getAktor()+aksiyon.getAdimTanim());
                        this.setAksiyonModu(true);
                    } else {
                        System.out.println("oduncStokTalep.getPendingAction() seems also null :"+oduncStokTalep.getPendingAction());
                        this.setAksiyonModu(false);
                    }
                }

                if (editModu && GO_Person_id!=null) {

                    if (oduncStokTalep.getSuAnKimde().contains(GO_Person_id.toString()) )
                        this.onaylamaYetkisi = true;

                    if (this.aksiyon != null && this.aksiyon.getAktor().contains(GO_Person_id.toString())) 
                        this.onaylamaYetkisi = true;
                }

            } else {
                System.out.println("viewID is null.");
                System.out.println("initializing OST...");
                this.editModu = false;
                this.setAksiyonModu(false);

                oduncStokTalep.setPersonId(GO_Person_id);        
            }
        } else oturumActirt();
    }

    // THE FOLLOWING METHOD IS EXECUTED PERFCETLY WITH A BLANK FORM AND WITH NO GET PARAMETER
    public String kaydet(){
        Long formId;
        System.out.println("invoking ost kaydet()...");

        ostServ.doPersist(oduncStokTalep);

        formId = oduncStokTalep.getId();
        System.out.println("OST MB obtained Id:"+formId);
        if (formId != null) {
            doSomeOtherStuff();
        }

        FacesUtil.setSessionAttribute("surecView", null);
        FacesUtil.setSessionAttribute("surecAdim", null);
        FacesUtil.setSessionAttribute("surecID", null);

        FacesContext fc = FacesUtil.getFacesContext();
        fc.addMessage(null, new FacesMessage("Ödünç Stok talebiniz başarıyla oluşturuldu ve "+formId+" no'lu ile sisteme kaydedildi."));

        oduncStokTalep = new OduncStokTalep("ost", "Ödünç Stok Talebi");

        return "KAYDETVEGONDER";
    }

    // This method is never even called form the update form :(((((
    public String onayla() throws NonexistentEntityException, Exception {
        System.out.println("Onayla() invoked for OST "+oduncStokTalep.getId());
        if (this.onaylamaYetkisi) {         
            System.out.println("onaylama yetkisi de var.");

            SomeActionController ac1 = new SomeActionController();

            if (aksiyon == null) 
                    aksiyon = ac1.getPendingAction("ost", this.viewID, String.valueOf(this.GO_Person_id));

            ac1.adimiTamamla(this.GO_Person_id, "ost", this.viewID, aksiyon.getId(), true, this.gorus);
        }

        oduncStokTalep = new OduncStokTalep("ost", "Ödünç Stok Talebi");

        return "DASHBOARD";
    }

    // Neither this one via <h:commandButton action="#{oduncStokTalepBean.test}" value="Test Action Method" />
    public void test() {
        System.out.println("Test OK");
    }

    // getters and setters, etc.

}

和 faces-config 片段:

<managed-bean>
  <managed-bean-name>surecBean</managed-bean-name>
  <managed-bean-class>net.ozar.wf.jsfmanaged.SurecBean</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
   <property-name>viewID</property-name>
   <property-class>java.lang.Long</property-class>
   <value>#{param.id}</value>
  </managed-property>
  <managed-property>
   <property-name>adimID</property-name>
   <property-class>java.lang.Long</property-class>
   <value>#{param.aid}</value>
  </managed-property>
  <managed-property>
   <property-name>surecID</property-name>
   <property-class>java.lang.String</property-class>
   <value>#{param.sid}</value>
  </managed-property>
 </managed-bean>
 <managed-bean>
  <managed-bean-name>oduncStokTalepBean</managed-bean-name>
  <managed-bean-class>net.ozar.wf.jsfmanaged.OduncStokTalepBean</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
   <property-name>viewID</property-name>
   <property-class>java.lang.Long</property-class>
   <value>#{param.id}</value>
  </managed-property>
  <managed-property>
   <property-name>adimID</property-name>
   <property-class>java.lang.Long</property-class>
   <value>#{param.aid}</value>
  </managed-property>
 </managed-bean>
4

2 回答 2

2

您正在使用该rendered属性来切换组件的可见性。当将此与请求范围的 bean 一起使用时,您需要确保在处理表单提交期间评估属性的相同条件rendered就像在显示表单期间一样。当rendered按钮或其父组件之一的属性条件为 时false,JSF 将不会调用该按钮。

如果您不能确保在 bean 的(后)构造过程中可以保留相同的条件,那么您需要将 bean 放在视图范围内(仅限 JSF 2.0)或使用 Tomahawk<t:saveState>在后续请求中保留 bean。

也可以看看:

于 2011-05-12T19:36:04.080 回答
0

检查是否在组件的任何设置器上生成错误。

于 2013-11-23T14:31:07.423 回答