JSF2复合组件为action方法抛出PropertyNotFoundException

Zac*_*ese 4 jsf composite-component jsf-2

我有一个复合组件:

<composite:interface>
    <composite:attribute name="actionMethod" 
        method-signature="java.lang.String action()" required="true" />
</composite:interface>

<composite:implementation>
    <h:form>
        <h:commandButton id="captureButton" value="#{msgs.capture}" 
            action="#{cc.attrs.actionMethod}" />
    </h:form>
</composite:implementation>
Run Code Online (Sandbox Code Playgroud)

和一个调用该复合组件的页面:

<ezcomp:captureTitle actionMethod="#{saveDecisionsBean.captureTitle}" />
Run Code Online (Sandbox Code Playgroud)

和一个包含动作的bean:

@Named(value="saveDecisionsBean")
@SessionScoped
public class SaveDecisionsBean extends BackingBeanBase {
    ...
    public String captureTitle() {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

现在这是我的问题.当我尝试运行它时,它说SaveDecisionsBean没有属性captureTitle.因此,我必须添加一个SaveDecisionsBean#getCaptureTitle()方法.当我这样做时,它运行得很好.我为什么要定义这个方法?它说它<composite:attribute />是一种方法,它被用作一种动作.

这是我得到的确切错误消息:

javax.el.PropertyNotFoundException: /index.xhtml @54,86 
    actionMethod="#{saveDecisionsBean.captureTitle}": 
    The class 'com.example.persistence.SaveDecisionsBean_$$_javassist_209'
    does not have the property 'captureTitle'.
Run Code Online (Sandbox Code Playgroud)

(出于SEO原因:其他实现可能会显示类名WeldClientProxy.)

Jor*_*gen 9

我有同样的问题,我发现这是由于我的动作方法确实抛出了IllegalArgumentException.同时这已被报告为一个错误:当方法抛出任何异常时,复合操作方法抛出PropertyNotFoundException.

棘手的部分(至少对我来说)是我的应用程序一直工作正常,直到我将部分代码移动到复合组件(CC).在我的应用程序捕获IAE并显示一个很好的错误消息之前,但在使用CC时,JSF验证(或其他......)首先捕获这个并产生这个相当混乱的错误消息.

我通过使用BalusC提供的测试代码的修改版本来验证这一点(见下文).测试页面显示两个输入和提交按钮组件.如果您在文本字段中输入内容(除了"恐慌"(没有引号)),CC版本和"内联"版本都可以工作(观看标准输出).如果你在"内联"版本中输入"panic",你会发现IAE符合预期,但如果你在上面的"CC-version"中输入相同的东西,你会看到PropertyNotFoundException.似乎JSF被IAE弄糊涂了,并且决定该属性必须是属性而不是动作方法...不确定这是一个错误还是一个功能.这是根据Spec,有人知道吗?

所以,这里的结论是你不能在CC中使用带有异常的bean的动作方法.对我来说,这意味着我不能使用复合组件.伤心!

希望这可以帮助...

/resources/components/test.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
  <cc:attribute name="text"/>
  <cc:attribute name="action" method-signature="java.lang.String action()" required="true" />
</cc:interface>
<cc:implementation>
  <h:form>
    <h:inputText value="#{cc.attrs.text}"/>
    <h:commandButton value="submit" action="#{cc.attrs.action}" />
  </h:form>
</cc:implementation>
Run Code Online (Sandbox Code Playgroud)

/test.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:cc="http://java.sun.com/jsf/composite/components">
<h:head>
  <title>Test</title>
</h:head>
<h:body>
  <!-- text and cmd-button as cc -->
  <cc:test text="#{bean.text}" action="#{bean.submit}" />

  <hr/>

  <!-- text and cmd-buuton inline -->
  <h:form id="inline">
    <h:inputText value="#{bean.text}"/>
    <h:commandButton value="submit2" action="#{bean.submit}" />
  </h:form>
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)

最后的豆子:

@ManagedBean
@RequestScoped
public class Bean {

  private String text;

  public String getText() {
    return text;
  }

  public void setText(String text) {
    this.text = text;
  }

  public String submit() {
        if (text.equalsIgnoreCase("panic")){
          throw new IllegalArgumentException("Panic!");
        }

        System.out.println(text);

        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你完全正确!这绝对是个错误.我会向JSF男孩报告. (2认同)