小弟因工作需要现在在用JSF
在JSF的JSP页面中用到了dataTable
在datatable的一个column中用inputText
和后台的一个类(Name,自己写的)中的firstname(HtmlInputText型)进行绑定
代码如下
<h:column id="column2">
    <f:facet name="header">
        <h:outputLabel value="FirstName" style="font-weight: bold"/>
    </f:facet>
    <h:inputText id="firstname" binding="#{name.firstname}"/>
</h:column>
其中
datatable的value="#{user.names}"
user为一个Bean而names就是一个Name型的数组
name为datatable的var它老是说
Error setting property 'firstname' in bean of type null而当我用value的时候就没有问题
<h:column id="column2">
    <f:facet name="header">
h:outputLabel value="FirstName" style="font-weight: bold"/>
    </f:facet>
    <h:inputText id="firstname" value="#{name.firstname.value}"/>
</h:column>这至少可以说明我的name.firstname 不是null啊哪位大虾知道是怎么回事,该怎么解决啊?

解决方案 »

  1.   

    JSF 中组件的 binding 是指 这个 HTML 组件要 绑定到那个 Bean 上,这个 Bean 本身跟 这个 HTML 组件是 一个类型的, 这样才能 get / set ,上面你的代码中 
    <h:inputText id="firstname" binding="#{name.firstname}"/>
    这里 name.firstname 应该是个 HtmlInputText 类的实例, 而你说它是个 Name 类型,所以类型不对,如果你只是 让他执行  name.setFirstname(); 来填充值(像 Struts 那样),那么你就应该用 <h:inputText id="firstname" value="#{name.firstname}"/>
    如果要用 binding 属性就这样 <h:outputText id="myOutputText" binding="#{myBean.myOutputText}"/>用到 binding 还有一个地方很实用:
    在一个 dataTable 中要得到当前行号,比如:
    我这里 myBean.myTable 是个 DataTable 类型, 这样迭代总显示当前的行号,当你使用了分页时也能看到正确的行号,比如 第一页 10-20 , 第二页他就是 21-30 。
    <h:dataTable id="mytable" binding="#{myBean.myTable}" var ="myList">
       <h:outputText value="#{myTable.rowIndex}" />
    </h:dataTable>
    public class MyPageCode {  private HtmlOutputText myOutputText;  public HtmlOutputText getMyOutputText(){
        if(myInputText == null){
         // 从 ViewRoot 开始搜索 ID 为 myInputText 组件并赋值。
        UIComponent root = FacesContext.getCurrentInstance().getViewRoot();
        
         myOutputText= (HtmlInputText) findInDeep(root,"myOutputText");   }   return myOutputText;
              
      }  public void setMyInputText(HtmlInputText input){
        this.myInputText = input;
      }}   private UIComponent findInDeep(UIComponent root, String id ){
         Iterator kids = root.getChildrenAndFacets();
         while( kids.hasNext()){
           UIComponent current = (UIComponent) kids.next();
           if( id.equals(current.getId())
               return current;
           current = findInDeep(current,id);
           if(current !=null)
             return current;
         }
         return null;  }
      

  2.   

    我的firstname是HtmlInputText 类型啊
    它是Name类中的一个属性
    在<h:inputText id="firstname" binding="#{name.firstname}"/>
    中name对应的是一个Name型的数组
    也就是datatable的value对应的数组
    而firstname对应的就是Name类里的一个HtmlInputText 的属性另外JAVA里有DataTable这个类吗?
    这个类我在.NET里用过
    可在JAVA里好象没有这个类吧还有你写的代码中
    <h:outputText id="myOutputText" binding="#{myBean.myOutputText}"/>
    既然已经绑定了还需要要findInDeep方法吗?
    只要在Bean里有一个HtmlOutputText的属性
    就可以直接在getMyOutputText方法里
    return那个HtmlOutputText的属性就可以了吧当然这都是我个人的看法
    如果有什么不对的地方还请多多指教
      

  3.   

    写错了 Sun JSF 参考实现是 HtmlDataTable , 
    会先调用 binding.get 操作,作了些事情之后才 bingding.set  .按这个错误消息 Error setting property 'firstname' in bean of type null
    说的不是 firstname == null 而是在 firstname 前面就已经出现了 NullPointerException 。我以前没有 findInDeep 发现 NullPointerException , 具体的实现你可以到 
    http://javaserverfaces.java.net 下载源代码看看,  binding.get 和 binding.set 在什么时候被调用。
      

  4.   


    http://javaserverfaces.java.net
    这个网站怎么打不开啊