我有一个复合组件:
<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>
和一个调用该复合组件的页面:
<ezcomp:captureTitle actionMethod="#{saveDecisionsBean.captureTitle}" />
和包含动作的bean:
@Named(value="saveDecisionsBean")
@SessionScoped
public class SaveDecisionsBean extends BackingBeanBase {
...
public String captureTitle() {
...
}
}
现在这是我的问题。当我尝试运行它时,它说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'.
(出于SEO原因:其他实现可能会显示类名WeldClientProxy
。)
答案 0 :(得分:9)
我有同样的问题,我发现这是因为我的动作方法确实抛出了IllegalArgumentException。与此同时,这被报道为一个错误: Composite action method throws PropertyNotFoundException when method throws any exception。
棘手的部分(至少对我来说)是我的应用程序一直正常工作,直到我将部分代码移动到复合组件(CC)。在我的应用程序捕获IAE并显示一个很好的错误消息之前,但在使用CC时,JSF验证(或其他......)首先捕获此信息并产生这个相当混乱的错误消息。
我通过使用BalusC提供的测试代码的修改版本来验证这一点(见下文)。测试页面显示两个输入&amp;提交按钮组件。如果您在文本字段中输入内容(除了“恐慌”(没有引号)),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>
/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>
最后是Bean:
@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;
}
}
答案 1 :(得分:1)
奇怪,我无法用Mojarra 2.0.2重现这一点。也许代码中有更多内容与一个或另一个相撞?或者你没有运行你认为正在运行的代码?
为了完整起见,我将包含我曾经尝试重现此问题的测试片段:
/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="action" method-signature="java.lang.String action()" required="true" />
</cc:interface>
<cc:implementation>
<h:form>
<h:commandButton value="submit" action="#{cc.attrs.action}" />
</h:form>
</cc:implementation>
</html>
/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>
<cc:test action="#{bean.submit}" />
</h:body>
</html>
com.example.Bean
package com.example;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class Bean {
public String submit() {
System.out.println("submit");
return null;
}
}
上述内容对你有用吗?