2011-03-27 23 views
5

Estoy tratando de obtener un componente compuesto que trabaje con su propio bean de respaldo, usando el ejemplo en p375 del libro Core JSF 3, pero solo obtenga un NPE. El problema parece estar al comienzo de encodeBegin(), Date date = (Date) getValue() devuelve null. Si soy sincero, realmente no entiendo dónde se supone que se va a almacenar el valor del componente , lo especifico como java.util.Date usando cc: attribute type =, pero I en realidad no lo entiendo entiendo cómo esto: public Object getSubmittedValue() {return this; } - que devolverá una instancia de una clase InputDateBean - da como resultado una Fecha. En general, soy bueno y estoy confundido por cómo se supone que funciona.Componente compuesto JSF con bean de respaldo

A diferencia del ejemplo de libro, estoy tratando de utilizar el componente de respaldo para el almacenamiento temporal, así que cuando ingresa el día trato de guardarlo en # {cc.day}, en el libro que usan una aplicación con ámbito de frijol alguna razón.

Gracias por cualquier ayuda. Estoy usando 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 
} 

Respuesta

2

ahora veo mi error. El problema es que el componente compuesto tiene que ser llamado con un objeto Date, es decir, <cclib:inputDate value="#{bean.date}"/>. Como el código es válido, la fecha debe crearse una instancia, pero no fue así. La manera más robusta de hacer esto es hacer una nueva Fecha() en encodeBegin() en el caso de que getValue() sea nulo. Esto funciona igual h: inputText/f: convertDateTime que no requiere que el valor sea instanciado.

Cuestiones relacionadas