Confusion JSF更新Backing bean中输入文本的值

时间:2014-02-19 19:06:23

标签: jsf primefaces

今天,我正在解决JSF中的一个小问题。实际上,我的InputText页面上有一个xhtml readyOnly属性设置为true。点击一个布尔值checkbox时,我应该输入文本可编辑,表示readyOnly错误。代码有点像这样。

  <div class="div-form-col" >
            <h:outputLabel value="#{msgs.violationAmount} " for="violationAmt" />

      <h:inputText value="#{outpassMBean.violationWebDTO.violationAmount}" id="violationAmt" readonly="true"/>

    </div>

<div class="div-form-row">
                      <div class="div-form-col">
                          <h:outputLabel value="#{msgs.violationExemptionApplicable} " for="violationExempted" />
                          <h:selectBooleanCheckbox value="#{outpassMBean.violationWebDTO.violationExemptionApplicable}" id="violationExempted" onchange="makeViolationAmountEditable(this);">
                          </h:selectBooleanCheckbox>

                      </div>
                  </div>

该方法的脚本如下: -

function makeViolationAmountEditable(id){
  alert("Ben");
  document.getElementById('violationAmt' ).readOnly=false;
  alert("Done");
}

现在我的第一个问题是,如果我正在编辑文本字段中的值,我如何更新backing Bean中的violationAmt的值。什么是最好的方式?当我使用PrimeFaces时,我遇到了概念remoteCommand。所以这就是我添加的内容。

<p:remoteCommand name="makeViolationAmountEditableOnServer" action="#{outpassMBean.makeViolationAmountEditable}" update="amountPanelApplicant"/>

支持bean级别的方法是这样的

public void makeViolationAmountEditable(){
//Set updated value 
setUpdatedViolationAmount(violationWebDTO.getViolationAmount());
//Some other code.
}

问题在于,每当此代码运行时,违规WebDTO中的违规金额是旧的,而不是我在输入字段可编辑后输入的金额。虽然我在firebug中看到更新的值是请求的一部分但是在支持bean中,然而仍然旧的值被引用。我不明白为什么?

我的大四学生告诉我,你正在更新客户端而不是服务器端的readOnly值,并更新了我的代码。

<p:outputPanel id="amountPanelApplicant">
          <p:outputPanel  rendered="#{outpassMBean.violationWebDTO.violationForCmb eq 2 and outpassMBean.violationWebDTO.isViolationExists}">
              <p:outputPanel styleClass="div-form twoCol">
                  <div class="div-form-row">
                      <div class="div-form-col" >
                          <h:outputLabel value="#{msgs.violationAmount} " for="violationAmt" />

                          <h:inputText value="#{outpassMBean.violationWebDTO.violationAmount}" id="violationAmt" readonly="#{outpassMBean.violationAmtEditable}">

                          </h:inputText>

                      </div>

                      <div class="div-form-col">
                          <h:outputLabel value="#{msgs.outPayTot} " for="totalViolationAmount" />
                          <h:outputLabel styleClass="readOnly" value="#{outpassMBean.violationWebDTO.totalViolationAmount}" id="totalViolationAmount" />
                      </div>
                  </div>

              </p:outputPanel>

              <p:outputPanel styleClass="div-form twoCol" rendered="#{outpassMBean.outpassApplication.applicationSubType.id eq 2 }" >
                  <div class="div-form-row">
                      <div class="div-form-col">
                          <h:outputLabel value="#{msgs.violationExemptionApplicable} " for="violationExempted" />
                          <h:selectBooleanCheckbox value="#{outpassMBean.violationWebDTO.violationExemptionApplicable}" id="violationExempted" onchange="makeViolationAmountEditableOnServer();">
                          </h:selectBooleanCheckbox>
                          <p:remoteCommand name="makeViolationAmountEditableOnServer" action="#{outpassMBean.makeViolationAmountEditable}" update="amountPanelApplicant"/>

                      </div>
                  </div>
              </p:outputPanel>
</p:outputPanel>

public void makeViolationAmountEditable(){
    if(logger.isDebugEnabled()){
      logger.debug("Inside makeViolationAmountEditable...");
    }
    //setting violation amount editable flag
    setViolationAmtEditable(false);

    //Preserving original and total amount.
    setOriginalViolationAmt(violationWebDTO.getViolationAmount());
    setOriginalTotalViolationAmount(violationWebDTO.getTotalViolationAmount());

  }

在上面更新的代码中,没有调用javascript。 readyOnly值从辅助bean本身设置为true和false。在此更新之后,基本上新的编辑值已在violationWebDTO中更新。

有人可以解释一下吗?为什么不在第一个快照?这不是一个完整的代码,但我试图解释混乱。任何指针都会有所帮助。

1 个答案:

答案 0 :(得分:2)

这是JSF防范篡改/黑客请求的安全措施,其中最终用户使用客户端语言/工具(如HTML或JS)以JSF&#的结果来操纵HTML DOM树和/或HTTP请求参数39; s disabledreadonly或甚至rendered属性被更改。

想象一下,如果JSF开发人员在这样的布尔属性中检查用户的角色会对管理员角色如disabled="#{not user.hasRole('ADMIN')}"进行检查会发生什么,并且黑客以这样的方式对其进行操纵已禁用非管理员用户。这正是您只能在服务器端更改上述属性(以及required属性以及所有转换器,验证器,事件侦听器等)的原因。

然而,如果没有<p:remoteCommand>和其他bean方法,可以以更简单的方式解决这个问题,而无需额外的属性。

<h:inputText id="violationAmount" ... readonly="#{makeViolationAmountEditable.value}" />
...
<h:selectBooleanCheckbox binding="#{makeViolationAmountEditable}">
    <f:ajax render="violationAmount" />
</h:selectBooleanCheckbox>

另见: