我正在尝试构建一个简单的组件来了解 JSF 2.X 如何以及为什么会以它的方式工作。我一直在使用较新的注释,并试图拼凑出一个清晰的例子。
所以我已经构建了我的组件并将其部署在一个 xhtml 文件中,如下所示:
<kal:day value="K.Day" title="Kalendar" model="#{kalendarDay}"/>
在 UIComponent 中,我执行以下操作:
ValueExpression ve = getValueExpression("model");
if (ve != null)
{
System.out.println("model expression "+ve.getExpressionString());
model = (KalendarDay) ve.getValue(getFacesContext().getELContext());
System.out.println("model "+model);
}
表达式“#{kalendarDay}”正确显示,表明该值已在页面和组件之间成功传输。但是,表达式的评估结果为“null”。
这似乎表明此时支持 bean 不可用,尽管页面正确验证和部署。所以我有 95% 的把握 bean 在运行时就在那里。
所以也许这是一个阶段的事情?我应该在渲染器的解码中对此进行评估并在属性映射中设置值吗?对于实际值和值表达式的组合,我仍然有些困惑。
所以我的问题是我应该在哪里获取和评估模型的 valueExpression,我应该将评估结果存储在 UIComponent 中还是应该每次都简单地评估它?
下面的 SSCCE 文件我认为这些是演示问题所需的唯一文件
Bean接口-----
/**
*
*/
package com.istana.kalendar.fixture;
import java.util.Date;
/**
* @author User
*
*/
public interface KalendarDay
{
public Date getDate();
}
Bean 实现 ---
/**
*
*/
package com.istana.kalendar.session.wui;
import java.util.Calendar;
import java.util.Date;
import javax.ejb.Stateful;
import javax.inject.Named;
import com.istana.kalendar.fixture.KalendarDay;
/**
* @author User
*
*/
@Named ("kalendarDay")
@Stateful
public class KalKalendarDay
implements KalendarDay
{
private Calendar m_date = Calendar.getInstance();
/* (non-Javadoc)
* @see com.istana.kalendar.fixture.KalendarDay#getDate()
*/
@Override
public Date getDate()
{
return m_date.getTime();
}
}
界面组件 ---
/**
*
*/
package com.istana.kalendar.fixture.jsf;
import javax.el.ValueExpression;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIOutput;
import com.istana.kalendar.fixture.KalendarDay;
/**
* @author User
*
*/
@FacesComponent (value=UIDay.COMPONENT_TYPE)
public class UIDay extends UIOutput
{
static final
public String COMPONENT_TYPE = "com.istana.kalendar.fixture.jsf.Day";
static final
public String COMPONENT_FAMILY = "com.istana.kalendar.fixture.jsf.Day";
private KalendarDay m_model;
private String m_title;
@Override
public String getRendererType()
{
return UIDayRenderer.RENDERER_TYPE;
}
@Override
public String getFamily()
{
return COMPONENT_FAMILY;
}
public KalendarDay getModel()
{
KalendarDay model = (KalendarDay) getStateHelper().eval("model");
System.out.println("model "+model);
return model;
}
public void setModel(KalendarDay model)
{
getStateHelper().put("model",model);
}
public String getTitle()
{
return (String) getStateHelper().eval("title");
}
public void setTitle(String title)
{
getStateHelper().put("title",title);
}
}
UIComponentRenderer ---
/**
*
*/
package com.istana.kalendar.fixture.jsf;
import java.io.IOException;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.FacesRenderer;
import javax.faces.render.Renderer;
import com.istana.kalendar.fixture.KalendarDay;
/**
* @author User
*
*/
@FacesRenderer (componentFamily = UIDay.COMPONENT_FAMILY
,rendererType = UIDayRenderer.RENDERER_TYPE
)
public class UIDayRenderer extends Renderer
{
static final
public String RENDERER_TYPE = "com.istana.kalendar.fixture.jsf.DayRenderer";
@Override
public void encodeBegin (FacesContext context,UIComponent component)
throws IOException
{
UIDay uic = (UIDay) component;
ResponseWriter writer = context.getResponseWriter();
writer.startElement("p", uic);
/*
* This is the call that triggers the println
*/
writer.write("Day - "+uic.getModel().getDate());
}
@Override
public void encodeEnd (FacesContext context,UIComponent component)
throws IOException
{
ResponseWriter writer = context.getResponseWriter();
writer.endElement("p");
writer.flush();
}
}
kalendar.taglib.xml ---
<facelet-taglib
id="kalendar"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0"
>
<namespace>http://istana.com/kalendar</namespace>
<tag>
<tag-name>day</tag-name>
<component>
<component-type>com.istana.kalendar.fixture.jsf.Day</component-type>
</component>
</tag>
</facelet-taglib>