2015-10-18 74 views
1

好PostConstruct方法,我使用的是ConversationScoped,我希望PostConstruct被稱爲只是一個時間在談話的開始,請參閱:ConversationScoped bean的呼籲在每次請求

@Named("disciplinaDetalheMB") 
@ConversationScoped 
public class DisciplinaDetalheMBImpl { 

    private static final long serialVersionUID = 1L; 

    @Inject 
     private Conversation conversation; 

    @Inject 
    @AnBasicBO 
    private BasicBO boPadrao; 

@PostConstruct 
    public void postConstruct() { 
    logger.debug("Iniciando PostConstruct..."); 
    init(); 
    beginConversation(); 
    } 

public String salvarAndRedirecionar() { 
    salvar(); 
    if (!FacesContext.getCurrentInstance().isValidationFailed()) { 
     return goToLastPage() + "?faces-redirect=true"; 
    } else { 
     return ""; 
    } 
    } 


private void beginConversation() { 
    if (!conversation.isTransient()) { 
     endConversation(); 
    } 
    conversation.begin(); 
    if (conversation.isTransient()) { 
     throw new RuntimeException("A conversão não foi iniciada corretamente"); 
    } 
    SessionContext.getInstance().setAttribute("cid", conversation.getId()); 

    } 

    public BasicBO getBoPadrao() { 
     return boPadrao; 
    } 

    public void setBoPadrao(BasicBO boPadrao) { 
     this.boPadrao = boPadrao; 
    } 

} 

所以,當我支持bean是創建後,會話被初始化,CID存儲在會話中以供後續使用。我有一個命令「保存」在我的XHTML,當該按鈕被稱爲PostConstruct再次被調用,我不知道爲什麼:

<h:commandLink 
      action="#{managedBeanName.salvarAndRedirecionar()}" 
      styleClass="btn btn-info pull-right" value="Salvar"> 
      <f:ajax execute="@form" /> 
     </h:commandLink> 

我注意到生成的HTML是:

<a id="formManterDisciplina:j_idt44:j_idt46" href="#" onclick="mojarra.ab(this,event,'action','@form',0);return false" class="btn btn-info pull-right" name="formManterDisciplina:j_idt44:j_idt46">Salvar</a> 

所以,我明白「href =#」可以避免onlick被執行。我認爲這是問題,但我不知道如何解決。 Remenber:salvarAndRedirecionar()方法永遠不會被調用,因爲postConstruct總是在之前被調用。

2)我還有一個問題:如果我開始一個會話,並沒有結束,有一些問題?有時我不想手動結束對話,因爲我只有一頁,我剛開始。

+0

這個班的範圍是什麼?爲什麼不向我們展示更多類的定義? –

+0

這是第* n *次必須從[jsf]問題中刪除[java]標記的時間。你能否把這個提示作爲一個提示,在未來的[jsf]問題中不再添加[java]標籤?只有當你有一個可以在Java應用程序類中用'main()'方法重現的問題時才使用[java]標籤。如果您有這樣的問題,那麼您應該重新考慮[jsf]和其他Java EE相關標記的相關性。 – BalusC

+0

對不起。 – RonaldoLanhellas

回答

2

您出現此問題的原因是因爲您正在調用對話作用域bean的postconstruct方法中的對話begin方法。因此,會話在渲染響應階段將設置爲長時間運行狀態,而不是在此之前。問題在於CID參數在HTML表單元素上呈現,但此時對話仍然處於臨時狀態,因爲postconstruct方法在請求之後尚未調用。 redenring的commandLink元素時postconstruct方法被調用,然後是爲時已晚,HTML表單元素將不攜帶CID參數:

<form id="yourForm" name="yourForm" method="post" action="/path/to/yourPage.xhtml" enctype="application/x-www-form-urlencoded">

因此,該解決方案包括移動談話的開始在渲染響應階段之前的一個點。如果您使用JSF 2.2或f:event標籤(如果您使用的是舊版本),則可以使用f:viewAction標籤。

,然後你會看到CID參數渲染HTML表單元素裏面,像這樣:

<form id="yourForm" name="yourForm" method="post" action="/path/to/yourPage.xhtml?cid=1" enctype="application/x-www-form-urlencoded">

  • 如果使用f:event標籤:

在你的頁面:

<f:metadata> 
    <f:event listener="#{disciplinaDetalheMB.initConversation}" type="preRenderView" /> 
</f:metadata> 

在你的ba盛泰豆:

public void initConversation(){ 
    if (!FacesContext.getCurrentInstance().isPostback() && conversation.isTransient()) { 
      conversation.begin(); 
    } 
} 
  • 如果使用f:viewAction標籤:

在你的頁面:

<f:metadata> 
    <f:viewAction action="#{disciplinaDetalheMB.initConversation}" /> 
</f:metadata> 

在支撐bean:

public void initConversation(){ 
    if (conversation.isTransient()) { 
      conversation.begin(); 
    } 
} 

關於你的第二個質疑在沒有結束對話的情況下,re不是個大問題,因爲它有一個像HTTP會話那樣的超時。您可以根據您的服務器資源管理策略和空閒會話的所需生命週期設置超時值。無論如何,當你只有一個頁面時,你最好使用一個視圖範圍的支持bean。

+0

工作得很好,謝謝。但是我不能將@ ViewScoped(jsf註釋)與@Named(CDI註釋)混合,發生錯誤。你可以幫我嗎 ? – RonaldoLanhellas

+0

如果您使用JSF 2.2,則使用'javax.faces.view.ViewScoped',但不要使用'javax.faces.bean.ViewScoped'。 – lametaweb

+0

現在工作,再次感謝你。但我讀過一些文章,這不是一個很好的練習,混合使用JSF註釋和CDI註解,這是真的嗎?如果是,爲什麼?正常工作沒有任何問題。 – RonaldoLanhellas