2011-03-27 128 views
5

我試圖用Core JSF 3書中的p375上的例子來獲得一個使用它自己的支持bean的複合組件, ,但只是得到一個NPE。問題似乎是在encodeBegin()的開始,Date date =(Date)getValue()返回null。 如果我說實話,我真的不知道組件的值應該被存儲在哪裏,我使用cc:attribute type =將它指定爲java.util.Date,但我不確定它是否爲 理解如何這樣:public Object getSubmittedValue(){return this; } - 這將返回一個InputDateBean類的實例 - 導致一個Date。我總體上很好,並且被這個應該如何工作所困惑。帶支持bean的JSF複合組件

與我試圖將臨時存儲的使用支持組件, 不同的是,當輸入日期時,我嘗試將它存儲在#{cc.day}中,在它們使用應用程序作用域bean的書中一些原因。

感謝您的任何幫助。我正在使用Mojarra 2.1。

inputDate.xhtml

<cc:interface componentType="uk.co.myco.jsfbeans.sqcc.InputDateBean"> 
    <cc:attribute name="value" type="java.util.Date"/> 
</cc:interface> 

<cc:implementation> 
    <h:panelGrid columns="3"> 
     <h:inputText id="day" value="#{cc.day}" 
        converter="javax.faces.Integer"/> 
     <h:inputText id="month" value="#{cc.month}" 
        converter="javax.faces.Integer"/> 
     <h:inputText id="year" value="#{cc.year}" 
        converter="javax.faces.Integer"/> 
    </h:panelGrid> 
</cc:implementation> 

InputDateBean.java

package uk.co.myco.jsfbeans.sqcc; 


import java.io.IOException; 
import java.util.Calendar; 
import java.util.Date; 
import javax.faces.component.FacesComponent; 
import java.util.GregorianCalendar; 
import javax.faces.application.FacesMessage; 
import javax.faces.component.NamingContainer; 
import javax.faces.component.UIInput; 
import javax.faces.context.FacesContext; 
import javax.faces.convert.ConverterException; 
import uk.co.myco.general.SQLog; 
import uk.co.myco.jsfbeans.helper.Messages; 

@FacesComponent(value = "uk.co.myco.jsfbeans.sqcc.InputDateBean") 
public class InputDateBean extends UIInput implements NamingContainer { 

    private int day = 0, month = 0, year = 0; 

    public InputDateBean() { 
    } 

    @Override 
    public String getFamily() { 
     return "javax.faces.NamingContainer"; 
    } 

    @Override 
    public void encodeBegin(FacesContext context) throws IOException { 
     Date date = (Date) getValue(); 
     Calendar cal = new GregorianCalendar(); 
     cal.setTime(date); 
     UIInput dayComponent = (UIInput) findComponent("day"); 
     UIInput monthComponent = (UIInput) findComponent("month"); 
     UIInput yearComponent = (UIInput) findComponent("year"); 
     dayComponent.setValue(cal.get(Calendar.DATE)); 
     monthComponent.setValue(cal.get(Calendar.MONTH) + 1); 
     yearComponent.setValue(cal.get(Calendar.YEAR)); 
     super.encodeBegin(context); 
    } 

    @Override 
    public Object getSubmittedValue() { 
     return this; 
    } 

    @Override 
    protected Object getConvertedValue(FacesContext context, Object newSubmittedValue) 
      throws ConverterException { 
     UIInput dayComponent = (UIInput) findComponent("day"); 
     UIInput monthComponent = (UIInput) findComponent("month"); 
     UIInput yearComponent = (UIInput) findComponent("year"); 
     int lday = (Integer) dayComponent.getValue(); 
     int lmonth = (Integer) monthComponent.getValue(); 
     int lyear = (Integer) yearComponent.getValue(); 
     if (isValidDate(lday, lmonth, lyear)) { 
      return new GregorianCalendar(lyear, lmonth - 1, lday).getTime(); 
     } else { 
      FacesMessage message = Messages.getMessage("util.messages", "invalidDate", null); 
      message.setSeverity(FacesMessage.SEVERITY_ERROR); 
      throw new ConverterException(message); 
     } 
    } 
    // getters & setters & isValidDate() removed 
} 

回答

2

我現在看到我的錯誤。問題在於複合組件必須是用Date對象調用的 ,即<cclib:inputDate value="#{bean.date}"/>.由於 代碼表示日期需要實例化,但事實並非如此。如果 執行得更健壯,則在 getValue()爲空的情況下,在encodeBegin()中執行新的Date()。然後這同樣工作h:inputText/f:convertDateTime 它不需要實例化該值。