2012-02-20 16 views
6

Estoy desarrollando una aplicación JSF2/Primefaces y tengo problemas para acceder a los atributos definidos en una interfaz de un componente compuesto en el bean de respaldo de este componente.Acceso a los atributos de componentes compuestos JSF2 en el componente de respaldo

Mi componente se define de la siguiente manera:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:composite="http://java.sun.com/jsf/composite"> 

<composite:interface componentType="testComponent"> 
    <composite:attribute name="text" required="true" type="java.lang.String" /> 
</composite:interface> 

<composite:implementation> 

    <h:outputText value="Passed text is: #{cc.attrs.text}" /> 

</composite:implementation> 

</html> 

Se almacena en un archivo llamado text.xhtml ubicado en: application/src/main/webapp/resources/my_component directorio.

Puedo utilizar este componente en otra página (que es un elemento de composición de Facelets) de este modo:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:myc="http://java.sun.com/jsf/composite/my_component" 
    template="./resources/templates/template.xhtml"> 

<ui:define name="content"> 
    <h:form id="products"> 
     <myc:test id="test" text="A text" /> 
    </h:form> 
</ui:define>  

</ui:composition> 

La clase de componente de soporte se define como sigue:

package my.application.component; 

import javax.faces.component.FacesComponent; 
import javax.faces.component.UINamingContainer; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

@FacesComponent (value="testComponent") 
public class TestComponent extends UINamingContainer { 
    Logger log = LoggerFactory.getLogger(TestComponent.class); 

    public TestComponent() { 
     log.debug("TestComponent constructor"); 
     log.debug("getAttributes().size(): " + getAttributes().size()); 
    } 
} 

El componente en sí funciona como esperado. La página de uso muestra la salida Passed text is: A text. Además, la salida del registrador muestra mensajes de registro del constructor TestComponent, por lo que parece que la definición del componente xml está correctamente enlazada con la clase TestComponent.

Ahora, el problema es que el método invocado en getAttributes()TestComponent constructor siempre devuelve un mapa de tamaño cero. Si entiendo esto correctamente, debería ser capaz de acceder al atributo text declarado en la interfaz del componente mediante una llamada:

getAttributes().get("text");

en la clase TestComponent, pero siempre vuelve null como el mapa de atributos está vacía.

También intentó acceder el atributo text mediante una llamada:

String text = FacesContext.getCurrentInstance().getApplication(). evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{cc.attrs.text}", String.class));

pero también resuelve a null.

¿Qué estoy haciendo mal? Cualquier consejo será muy apreciado ya que no tengo idea de qué probar a continuación.

/Tukasz.

Respuesta

5

Supongo que el constructor es demasiado pronto para hacer referencia a esos atributos.

JSF construirá primero una instancia del componente de respaldo y, en algún momento, le dará una referencia a sus atributos. En un método que se llama más tarde, por ejemplo, el método de codificación, debe tener acceso a ellos.

+0

Hola Mike. Gracias. Lo intentaré y verifico si los atributos están accesibles en el método 'encode'. –

+0

Hola de nuevo. Sí. Los atributos son accesibles en los métodos 'encode [All | Begin | End | Childen] (FacesContext context)'. Muchas gracias por la ayuda. Pero todavía me pregunto si uno de estos métodos es el lugar correcto para acceder a los atributos si quiero usarlos de alguna manera antes de que se represente mi componente. En un '@ ManagedBean's uso los métodos' @ PostConstruct' para tal fin, pero esto no parece funcionar en una clase '@ FacesComponent'. –

+2

¿Tal vez alguien debería presentar una solicitud para eso? '@ PostConstruct' en' @ FacesComponent' sería genial! –

Cuestiones relacionadas