日期:2014-05-16 浏览次数:20482 次
【续前。。。。。。】
八、步骤二:编写标签处理器类
UI组件类不同于普通Java类的地方是,它不是在Java代码中被引用,而是在JSP文件中。在JSP文件中,我们不能通过new操作符实例化UI组件类,只能通过JSP标签引用和实例化UI组件类。
前文介绍过如何引用一号组件,即在JSP文件中写入类似这样的标签即可:
<x:repeatText text="Hello world!" number="3">
当
JSP引擎读到这个标签时,它会把x:repeatText翻译为对某个类的调用,这个类就是所谓的标签处理器类tag
handler。JSP引擎会将组件类的一个实例传递给标签处理器类,标签处理器类的功能是给这个组件类实例的各个属性赋值,值的来源就是标签中的
text="Hello world!" number="3"。
可见,JSP引擎和标签处理器类配合工作,可以实现类似于Java代码
中实例化一个类并给类的属性赋值的功能。我们在JSP文件中写下<x:repeatText text="Hello world!"
number="3">,实际上就相当于实例化一号组件类并给其text和number分别赋值“Hello world!”和“3”。图
7示出了JSP标签和普通Java代码的类比。
?
也许你已经留意到图 7中标签名repeatText和组件类名StrRepeat之间的不同,它们是如何对应的,我们将在后文解释。
理解了标签处理器类的作用后,我们就很容易编写它的代码了。如同组件类StrRepeat可以继承UIComponentBase类一样,标签处理器类也可
以继承JSF框架提供的几个标签处理父类,以减少代码量。例如,一号组件的标签处理类可以继承UIComponentELTag类,如果我们将一号组件的
标签处理器类命名为StrRepeatTag,则其声明为:
public class StrRepeatTag extends UIComponentELTag{ ... }?
标签处理器类的属性决定了我们允许用户在JSP文件中为自定义UI组件的哪些属性赋值。对于一号组件,我们允许用户在JSP标签中对一号组件的text和
number属性赋值,因此,StrRepeatTag类也必须有text和number这两个属性,用来接收用户在JSP标签中写入的值,然后转赋给一
号组件。这很容易,只需为StrRepeatTag类定义两个标准的JavaBeans属性即可,如程序清单 4所示。
程序清单 4 StrRepeatTag类的text和number属性
private String text; public String getText() { return text; } public void setText(String text) { this.text = text; } private int number; public int getNumber() { return number; } public void setNumber(int number) { this.number = number; }?
读者不难发现,这部分代码和一号组件类StrRepeat的(见程序清单 1)完全一样,甚至连属性名称都相同。当然,这不是强制要求,标签处理器类和相应的组件类的属性可以不同名,个数也可以不同,如果你无需允许用户在JSP标签中给组件类的所有属性赋值。
标签处理器类有几个方法,我们逐一说明:
1.??? 返回组件类型的方法getComponentType()(参见程序清单 5)
程序清单 5 标签处理器类StrRepeatTag的getComponentType()方法代码
@Override public String getComponentType() { return "MyComponentType"; }
?
这个方法返回一个称被为“组件类型”的字符串。组件类型决定了标签处理器类和组件类之间的对应关系,例如,当JSP引擎碰
到<x:repeatText.../>这样的标签时,之所以能够正确地判断出这是与StrRepeat组件类相对应的一个标签,正是由于“
组件类型”字符串起着牵线搭桥的作用。具体的对应方法,后文有更详细的说明。
父类UIComponentELTag中的getComponentType()方法是抽象的,因此必须在子类中实现它。本例中,我们返回的组件类型为MyComponentType,如程序清单 5所示。
2.??? 返回呈现器类型的方法getRendererType()(参见程序清单 6)
程序清单 6标签处理器类StrRepeatTag的getRendererType()方法代码
@Override public String getRendererType() { return null; //throw new UnsupportedOperationException("Not supported yet."); }?
呈现器是一种专门负责向http响应输出组件内容的类。JSF允许组件类自己输出自己的内容,也允许它假手于人,即交给与之对应的呈现器类来输出。这个方法
返回的呈现器类型,正是用来供JSF框架选择合适的呈现器类的。由于一号组件是自己负责输出,不需要呈现器类,因此,我们让这个方法简单地返回一个
null,即告诉JSF框架,一号组件没有对应的呈现器类。
父类UIComponentELTag中的getRendererType()方法是抽象的,因此必须在子类中实现它。
3.??? 给组件类实例赋值的方法setProperties()
程序清单 7标签处理器类StrRepeatTag的setProperties()方法代码
@Override protected void setProperties(UIComponent component) { super.setProperties(component); component.getAttributes().put("text", this.getText()); component.getAttributes().put("number", this.getNumber()); }?
我们已在前面提到,用户可以通过JSP标签给组件类实例的属性赋值,setProperties()方