无法在MyFaces

时间:2016-01-06 05:58:11

标签: jsf composite-component myfaces propertynotfoundexception

版本:MyFaces 2.2.8

问题: 我有一些复合组件,它将为从复合传递的变量赋值。 它适用于Mojara 2.2.12(在迁移到Myfaces 2.2.8之前)。

这是我的复合代码: info.xhtml

<composite:interface>
    <composite:attribute name="id" />
    <composite:attribute name="methodToGetRecordFromInfo" method-signature="java.util.List action(id.co.sg.core.Dto)" required="true" />
    </composite:interface>

<p:dataTable id="tblInfoCodeComponent"
  var="codeComponent"
  value="#{infoBean.grid}"

    <p:columnGroup type="header">
        <p:row>
            <p:column headerText="CodeComponent"/>
        </p:row>
    </p:columnGroup>

    <p:column>
          <p:commandLink value="#{codeComponent.map['componentCode']}"
                  process="@this"
                  icon="ui-icon-search"
                  update="#{infoBean.field.map['update']}">
          <f:setPropertyActionListener
            value="#{infoBean.wrap(codeComponent)}"
            target="#{cc.attrs.methodToGetRecordFromInfo}" />
          </p:commandLink>
    </p:column>

</p:dataTable>

这是复合bean代码中的方法 infoBean.java

public Dto wrap(Dto codeComponentRecord) {
    Dto result = new Dto();

    result.putString("callerId", "callerId");
    result.putDto("record", codeComponentRecord.clone());

    return result;
}

Dto,是我们用来简化作品的某种地图对象。

这就是我们在主xhtml中使用它的方式

input.xhtml

<info:codeComponentInfo id="codeComponentInfo" methodToGetRecordFromInfo="#{inputBean.selectedInfoRecord}" />   

这是inputBean.java中的代码

private Dto selectedInfoRecord;

public void setSelectedInfoRecord(Dto infoDto){

    String id = infoDto.getString("callerId","");
        activeRow.putDto("codeComponent", infoDto.getDto("record"));            

}

public Dto getSelectedInfoRecord() {
    return selectedInfoRecord;
}

当我使用MyFaces 2.2.8时,setSelectedInfoRecord方法不会调用。 所以,我无法从inputBean中的infoBean中获取结果。

然后我看到了这篇文章  Pass Argument to a composite-component action attribute

所以我将实际的info.xhtml代码修改为这个

<composite:interface>
   <composite:attribute name ="beanName" type="java.lang.Object"/>
   <composite:attribute name ="methodName" type="java.lang.String"/>
</composite:interface>

...

<f:setPropertyActionListener
  value="#{infoBean.wrap(codeComponent)}"
  target="#{cc.attrs.beanName[cc.attrs.methodName]}" />

这是新的input.xhtml

<info:goodsCodeComponentInfo id="goodsCodeComponentInfo"  beanName="infoBean" methodName="selectedInfoRecord"/> 

但这是我发现的

  

错误BusinessExceptionHandler - $$$$$发生未处理的异常   org.apache.myfaces.view.facelets.el.ContextAwarePropertyNotFoundException:javax.el.PropertyNotFoundException:Property&#39; selectedInfoRecord&#39;在类型java.lang.String

上找不到

然后我尝试将info.xhtml修改为这个

 <f:setPropertyActionListener
      value="#{infoBean.wrap(codeComponent)}"
      target="#{cc.attrs.beanName.methodName}" />

或者这个

<f:setPropertyActionListener
    value="#{infoBean.wrap(codeComponent)}"
    target="#{cc.attrs.beanName.selectedInfoRecord}" />

仍然有与上面相同的错误..

所以我尝试再次修改它到这个

<f:setPropertyActionListener
    value="#{infoBean.wrap(codeComponent)}"
    target="#{inputBean.selectedInfoRecord}" />

效果很好!!!但这不是我需要的,我需要从参数传递bean名称。

任何人都可以帮我解决这个问题吗?

我正在使用Java 8和tomcat 8.0.30以及EL 3

1 个答案:

答案 0 :(得分:2)

我已经检查了寻找可能的错误的问题,但没有错误。相反,它与理解f:setPropertyActionListener如何工作有关。

此标记将从EL表达式检索的值设置为“target”属性指向的属性。如果您尝试使用“target”属性调用方法,它将无法工作,因为这不是它的设计方式。

这样做的正确方法是:

<info:codeComponentInfo bean="#{inputBean}" methodName="selectedInfoRecord"/>

在复合组件中:

<cc:attribute name ="bean" type="java.lang.Object"/>
<cc:attribute name ="methodName" type="java.lang.String"/>
....
<f:setPropertyActionListener
                value="#{infoBean.wrap(codeComponent)}"
                target="#{cc.attrs.bean[cc.attrs.methodName]}" />

这里的关键是你需要传递对bean的引用,这样就可以正确地解决链。