根据 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";
}
我想要求用户在提交文件前输入密码。所以 <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";
}