初学jsf自定义标签时遇到的问题总结

初学jsf自定义标签时遇到的问题总结

1.定义一个标签要用到两个java类,这个跟jsp的自定义标签有点不一样
  第一个类继承UIComponentTag, 用于定义标签的属性和设置标签的所有属性值到控件的map属性attributes或valueBinding中
  第二个类继承UIInput或者UIOutput,用于渲染标签的内容,真正打印标签内容的地方就在这里
   
2.这两个类是怎么联系的
 我们需要像定义jsf的bean的影射文件一样,在faces-config.xml或者自己定义的xml文件里面定义第二个类
 如:
 
< faces-config >
  
<!-- 分页标签 -->
  
< component >
    
< component-type > pageTag </ component-type >
    
< component-class > com.jsf.PageComponent </ component-class >
  
</ component >
  
  
</ faces-config >
  然后第一个类要实现父类的一个方法 public String getComponentType();从这里返回一个字符串pageTag,这样就跟第二个类联系起来了

3.标签属性的定义
  标签属性的定义一般都是可转化为字符串的类型的,除非你还是用
< %=rowList % > 这种jsp赋值的方式
  别以为你定义的一个List类型的属性可以用jsf的EL表达式可以直接赋值进来,EL表达式传进来以后属性接收的就是这一串EL表达式
  所以就是说你的属性就是要字符串类型的

4.那么jsf自定义标签是怎么接收EL表达式绑定的列表的
 先通过父类的isValueReference(属性值),来判断该属性的值是否是一个EL的表达式
 如果是则通过获取绑定值得方式把真正的属性的值设置到标签父类的valueBinding对像中
 否则直接把属性的值添加到标签父类的attributes对像中
  if (isValueReference(属性值)) {
    javax.faces.el.ValueBinding vb = Util.getValueBinding(value.toString());
    component.setValueBinding(name, vb); //component就是标签对像,name就是标签的属性名称
 } else {
    component.getAttributes().put(name, 属性值);
 }

 这就是个设置属性值的过程,可以在第1点说的第一个类里面的protected void setProperties(UIComponent component)方法
5.现在知道标签属性值的作用了吗
 是的标签属性值只不过是起个作用而已,而不是我们真正所要的值
 也就是说我们是不能从这些属性中直接取值的
 
6.那么我们怎么取属性的真正的值呢
 可以先从第4点说的标签父类的attributes对像中取值
 如果取不到值那就到标签父类的valueBinding对像中取值
 说白了就是,通过第4步我们属性的真正的值不是放在attributes就是在valueBinding中
 Object obj = component.getAttributes().get(name); //component就是标签对像,name就是标签的属性名称
 if (obj == null) {
   ValueBinding vb = component.getValueBinding(name);
   if (vb != null) {
    return vb.getValue(context);
   } else {
    return null;
   }
 }
 这个过程就是取属性值的过程,在第1点说的第二个类里面进行
 
7.现在属性值也可以取到了,那么我们要怎么打印标签的内容呢
  我们可以在第二个类的encodeBegin或者encodeEnd中进行
  public void encodeBegin(FacesContext context) throws IOException
  public void encodeEnd(FacesContext context) throws IOException
 
  取属性值的过程也可以在这里进行,取完值后就是把值组装到标签内容的相应位置中就完了
  
  基本上就是这几点

你可能感兴趣的:(初学jsf自定义标签时遇到的问题总结)