下面的代碼來自一個支持bean。從<f:event listener="#{nextBean.async}" type="preRenderView"/>
的視圖調用async()
。由於我不希望此操作延遲視圖的呈現,因此會在EJB返回Future<Boolean>
時觸發@Asynchronous
-annotated方法。
只要此操作正在運行,我希望UI被阻止,因此我執行<p:remoteCommand>
觸發ready()
,它檢查Future
-Object是否有結果,這表示異步方法已完成,然後取消阻止UI。
問題:異步方法似乎被ready()
第二次調用。我怎樣才能達到我想要做的?如何正確使用Future <V>?
支持bean:
package mypackage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.java.Log;
@ManagedBean
@ViewScoped
@Getter
@Setter
public class NextBean {
@EJB private AsyncBean asyncBean;
private Future<Boolean> ready;
public void async() {
ready = asyncBean.async();
}
public void ready() {
try {
while (ready.get() != true) {
Thread.sleep(300);
}
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
的Facelets的代碼:
<html xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body id="wholeView">
<f:metadata>
<f:event listener="#{nextBean.async}" type="preRenderView"></f:event>
</f:metadata>
<p:blockUI id="blockui" block=":wholeView" widgetVar="blockUI">
please wait
</p:blockUI>
<h:form>
<p:remoteCommand onstart="blockUI.show();"
name="doIt"
id="dooo"
process="@this"
action="#{nextBean.ready}"
oncomplete="blockUI.hide();"
autoRun="true"
/>
</h:form>
CONTENT
</h:body>
</html>
的EJB:
package mypackage;
import java.util.concurrent.Future;
import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;
import lombok.extern.java.Log;
@Stateless
@Log
public class AsyncBean {
@Asynchronous
public Future<Boolean> async(){
try {
Thread.sleep(3000);
return new AsyncResult<Boolean>(true);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
UPDATE:
1.用戶被引導到從外部頁面查看(如支付流程的一部分)。
2.請求視圖業務邏輯應該被執行,它不應該延遲視圖的呈現,而是在執行業務邏輯時阻止視圖的UI。
謝謝你的回答。我更新了我的問題,並希望這會使功能需求更清晰。:) – Lester
我刪除了''和'',並在主體中添加了一個簡單的'#{nextBean.async()}',好像我得到了想要的結果。 –
Lester
可以。請注意,這仍然是同步的。那個'@ Asynchronous'然後完全是多餘的,只會浪費整個線程。另外,如果該方法沒有返回任何有用的HTML輸出用法,則可以在bean的(後)構造函數中完成這項工作。 – BalusC