微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

验证阶段失败后,Java Server Faces会继续显示旧值忽略actionListeners设置

如何解决验证阶段失败后,Java Server Faces会继续显示旧值忽略actionListeners设置

|| 我想请一些帮助理解JSF在验证阶段显示的特定行为 失败。 我在用着: 的Tomcat 7.0.2 JSF 1.2_12 RichFaces 3.3.3 问题描述。 我编写了一个包含4个输入字段的表单:一个inputText和3个selectOneMenu。 inputText是必需的 而selectOneMenus不需要任何验证。附加到第一个selectOneMenu(第32行), 是a4j:support标记,以便每当触发change事件时,第二个项目的列表 并且第三个selectOneMenu(第44和58行)已正确填充。特别是加载后 这两个项目列表,该方法强制第二个和第三个selectOneMenu的值 为空。在我提交表单而不填写输入内容之前,此机制似乎正常工作 文字:正如预期的那样,JSF验证失败,但是当我更改第一个selectOneMenu的值时, 该页面继续显示在第二次JSF验证失败之前指定的值,并且 第三个selectOneMenu(请注意,仍会调用actionListener,第二个和 第三个selectOneMenu仍被强制为null)。 由于我使用的是简单的PhaseListener,因此我注意到了以下几点: 在JSF验证失败之前,每次更改第一个selectOneMenu的值时,JSF的寿命 循环始终在渲染过程中为第二个和第三个selectOneMenu调用get方法。 响应阶段。这样,JSF能够“看到”那些值在执行期间已设置为null。 调用应用程序阶段。 验证失败后,当我更改第一个的值时,JSF停止调用这些获取器 selectOneMenu。 这是我的看法
<?xml version=\'1.0\' encoding=\'UTF-8\' ?> 
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" 
                      \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\"
      xmlns:f=\"http://java.sun.com/jsf/core\"
      xmlns:h=\"http://java.sun.com/jsf/html\"
      xmlns:a4j=\"http://richfaces.org/a4j\"
      xmlns:rich=\"http://richfaces.org/rich\">

<head>
  <title>Prove Rich</title>
</head>

<body>

  <h2>Prove Rich</h2>

  <f:view>

  <a4j:outputPanel ajaxRendered=\"true\">
    <h:messages style=\"color:red\" />
  </a4j:outputPanel>

  <h:form>

  <p>
    Input required: <h:inputText value=\"#{provaProbReplyBean.inputrequired}\" required=\"true\" />
  </p>

  <p>
    <h:outputText value=\"Scegli il canale:\" />
    <h:selectOneMenu value=\"#{provaProbReplyBean.canale}\">

       <f:selectItem itemLabel=\"--\" itemValue=\"\" />
       <f:selectItem itemLabel=\"Profamily\" itemValue=\"Profamily\" />
       <f:selectItem itemLabel=\"Captive\" itemValue=\"Captive\" />

       <a4j:support event=\"onchange\" action=\"#{provaProbReplyBean.caricaProcBanche}\" ajaxSingle=\"true\" reRender=\"procedure,banche\" />
    </h:selectOneMenu>
  </p>

  <p>
    <h:outputText value=\"Scegli la procedura:\" />
    <h:selectOneMenu id=\"procedure\" value=\"#{provaProbReplyBean.procedura}\">

       <f:selectItem itemLabel=\"--\" itemValue=\"\" />

       <f:selectItems value=\"#{provaProbReplyBean.procedureList}\" />

       <!-- immediately save the current value -->
       <a4j:support event=\"onchange\" ajaxSingle=\"true\" />

    </h:selectOneMenu>
  </p>

  <p>
    <h:outputText value=\"Scegli la banca:\" />
    <h:selectOneMenu id=\"banche\" value=\"#{provaProbReplyBean.banca}\">

       <f:selectItem itemLabel=\"--\" itemValue=\"\" />

       <f:selectItems value=\"#{provaProbReplyBean.bancheList}\" />

       <!-- immediately save the current value -->
       <a4j:support event=\"onchange\" ajaxSingle=\"true\" />

    </h:selectOneMenu>
  </p>

  <p><h:commandButton value=\"Submit\" /></p>

  </h:form>

  </f:view>

</body>

</html>
这是我的模型:
public class ProvaProbReply {

    private String inputrequired;

    private String canale;
    private String procedura;
    private String banca;

    private Map<String,List<SelectItem>> canaliProc = new HashMap<String,List<SelectItem>>();
    private Map<String,List<SelectItem>> canaliBanche = new HashMap<String,List<SelectItem>>();

    private List<SelectItem> procedureList = new ArrayList<SelectItem>();
    private List<SelectItem> bancheList = new ArrayList<SelectItem>();

    public ProvaProbReply() {

        List<SelectItem> l = new ArrayList<SelectItem>();
        l.add(new SelectItem(\"Cessione del quinto\"));
        l.add(new SelectItem(\"Credito al consumo\"));
        l.add(new SelectItem(\"Mutui\"));

        canaliProc.put(\"Profamily\",l);

        l = new ArrayList<SelectItem>();
        l.add(new SelectItem(\"Credito al consumo\"));

        canaliProc.put(\"Captive\",l);

        l = new ArrayList<SelectItem>();

        canaliBanche.put(\"Profamily\",l);

        l = new ArrayList<SelectItem>();
        l.add(new SelectItem(\"BDL\"));
        l.add(new SelectItem(\"BM\"));
        l.add(new SelectItem(\"BPM\"));
        l.add(new SelectItem(\"CRA\"));

        canaliBanche.put(\"Captive\",l);
    }

    public String getInputrequired() {

        return inputrequired;
    }

    public void setInputrequired(String ir) {

        inputrequired = ir;
    }

    public String getCanale() {

        return canale;
    }

    public void setCanale(String c) {

        canale = c;
    }

    public String getProcedura() {

        System.out.println(\"\\ngetProcedura called\\n\");
        return procedura;
    }

    public void setProcedura(String p) {

        procedura = p;
    }

    public String getBanca() {

        System.out.println(\"\\ngetBanca called\\n\");
        return banca;
    }

    public void setBanca(String b) {

        banca = b;
    }

    public List<SelectItem> getProcedureList() {

        return procedureList;
    }

    public List<SelectItem> getBancheList() {

        return bancheList;
    }

    public String caricaProcBanche() {

        System.out.println(\"\\nListener called\\n\");

        procedureList.clear();
        bancheList.clear();

        if(canale != null && !canale.equals(\"\")) {

            procedureList.addAll(canaliProc.get(canale));
            bancheList.addAll(canaliBanche.get(canale));
        }

        System.out.println(\"BEFORE setting:\\n\");

        System.out.println(\"\\nProcedura: \"+procedura+\"\\n\");
        System.out.println(\"Banca: \"+banca+\"\\n\");

        procedura = null;
        banca = null;

        System.out.println(\"\\n\\n\\nAFTER setting:\\n\");

        System.out.println(\"\\nProcedura: \"+procedura+\"\\n\");
        System.out.println(\"Banca: \"+banca+\"\\n\");

        return \"\";
    }
}
    

解决方法

        听起来您正在观察
EditableValueHolder
类型的预期行为。 如果验证或类型转换失败,则将以提交状态重新提交表单。文档中的“申请请求值”阶段(JSF 2规范)对此进行了暗示:   在此阶段结束时,组件树中的所有“ 2”个组件都将使用此请求中包含的新提交值进行更新(或者,如果存在转换错误,则将存储足够的数据以重现错误的输入)。 如果转换或验证失败,那么将不会运行“更新模型值”阶段(不会在Bean上调用任何setter。)如果用户只是提交了复杂的表单,则他们不希望擦除所有字段,因为一个是错的。渲染器发出用户提交的值,并且不调用getter(请参见
isValid()
getSubmittedValue()
)。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。