根据 bean 字段值渲染表单

Rendering a form based on bean field value

我想要求用户在提交文件前输入密码。所以 <h:panelGroup> 应该在点击提交按钮后呈现。但是,<h:panelGoup> 永远不会被渲染。

test.xhtml

<ui:define name="body">
    <h:form id="uploadForm" enctype="multipart/form-data">
        <table>
            <t:inputFileUpload id="uploadedFile" storage="file"
                               value="#{UpdateBean.uploadedFile}"/>
            <h:commandButton value="Submit" action="#{UpdateBean.submit()}"/>
        </table>
    </h:form>

    <h:panelGroup id="checkPassword" rendered="#{UpdateBean.submitIsPerformed}">
        <h:outputText id="message" value="${UpdateBean.message}" />
        <h:inputText id="password" value="#{UpdateBean.password}" />
        <h:commandButton value="submit" action="#{UpdateBean.submitPassword()}"/>
    </h:panelGroup>
</ui:define>

UpdateBean.java

@ManagedBean(name = "UpdateBean")
@SessionScoped
public class UpdateBean {
    protected boolean submitIsPerformed = false;
    protected String password = "";
    protected String message = "Input your password ";

    // omit getter and setter

    public void submit() {
        this.setSubmitIsPerformed(true);
        System.out.println(submitIsPerformed); // output is true

        while(true) {
           if(password.equals("123")) {
               break;
           }
       }

       // then process uploadedFile
    }

    public void submitPassword(){
       if(password.equals("123")) {
          message = "Password confirmed !";
       } else {
          message = "Password is wrong !";
       }
    }
}

你的错误在submit()方法中:

while(true) {
   if(password.equals("123")) {
       break;
   }
}

while(true) 阻止操作方法 returning。只要操作方法不 return,服务器就不会 return 带有更新视图的 HTTP 响应。实际上,您的服务器之一 CPU 卡在 100% 并且客户端无限等待 HTTP 响应。如果有的话,您应该通过检查浏览器的进度指示器来注意到它。

切换布尔值后,您基本上应该立即return:

public void submit() {
    submitIsPerformed = true;
}

并在submitPassword()方法中执行密码检查和上传文件保存。但是,由于这不是同一种形式,上传的文件将会丢失。即使你把它放在同一个表格里,它也会被上传两次。但这是一个不同的问题。我建议反过来做。

按照@BalusC 的建议,这是我更新的代码。

test.xhtml

    <ui:define name="body">
        <h:form>
                        <h:commandButton value="Upload a file" action="#{UpdateBean.submit()}">
                            <f:ajax render=":checkPassword" />
                        </h:commandButton>
        </h:form>

        <h:form id="checkPassword" styleClass="toggle" rendered="#{UpdateBean.submitIsPerformed}">
            <table>
                <tr>
                    <td><h:outputText value="Password" /></td>
                    <td><h:inputText id="password" value="#{UpdateBean.password}" /></td>
                    <td>
                    <h:commandButton value="Submit" action="#{UpdateBean.submitPassword()}">
                        <f:ajax execute="password" render=":uploadFile" />
                    </h:commandButton>
                    </td>
                </tr>
            </table>
        </h:form>

        <h:form id="uploadFile" enctype="multipart/form-data"
                styleClass="toggle" rendered="#{UpdateBean.uploadFileIsPerformed}">

            <t:inputFileUpload id="uploadedFile" storage="file"
                               value="#{UpdateBean.uploadedFile}">
            </t:inputFileUpload>
            <h:commandButton value="Submit" action="#{UpdateBean.uploadFile()}" />
        </h:form>
    </ui:define>

UploadBean.java

   public String submit() {

        setSubmitIsPerformed(true);
        return "SUCCESS";
    }

    public String submitPassword(){
        if(password.equals("123"){
            setUploadFileIsPerformed(true);
            setSubmitIsPerformed(false);
        }
        return "SUCCESS";
    }

    public String uploadFile(){
        return "SUCCESS";
    }