Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JSF2-如何向复合组件接口添加Ajax侦听器方法?_Java_Ajax_Jsf 2_Listener_Composite Component - Fatal编程技术网

Java JSF2-如何向复合组件接口添加Ajax侦听器方法?

Java JSF2-如何向复合组件接口添加Ajax侦听器方法?,java,ajax,jsf-2,listener,composite-component,Java,Ajax,Jsf 2,Listener,Composite Component,我有一个JSF2复合组件,它采用了一些Ajax行为。我想在复合组件中的标记中添加侦听器方法,但是侦听器方法应作为中的提供 我的复合组件中的标记当前硬编码到侦听器,如下所示: bean上的侦听器方法具有以下签名: public void genericAjaxEventLogger(AjaxBehaviorEvent event) throws AbortProcessingException { // implementation code... } 我希望复合组

我有一个JSF2复合组件,它采用了一些Ajax行为。我想在复合组件中的
标记中添加
侦听器
方法,但是
侦听器
方法应作为
中的
提供

我的复合组件中的
标记当前硬编码到侦听器,如下所示:


bean上的侦听器方法具有以下签名:

public void genericAjaxEventLogger(AjaxBehaviorEvent event) 
        throws AbortProcessingException {
    // implementation code...
}
我希望复合组件是这样的,这样页面就可以提供自己的事件方法,但我无法找出接口的正确语法


我该怎么做?

使用解决方案更新:

我采用了BalusC建议的方法,效果很好。相关片段包括:

复合组件中的接口声明


...
复合组件中使用的Ajax标记


页面中使用复合组件的位置


以及我的支持bean上的方法

public void updatedEventListenerXYZ() {
    // do something here...
}

下面是一个关于如何使用接口设置属性并在实现中引用它的示例。您必须定义将被调用的方法的方法签名。这将通知复合组件处理程序#{cc.attrs.ajaxEventListener}表达式中包含方法值,而不是值表达式

<cc:interface name="composite-comp"
    <cc:attribute required="true" name="ajaxEventListener" 
                  method-signature="void f1(javax.faces.event.AjaxBehaviorEvent)" />
    <cc:attribute required="true" name="ajaxRenderTargets" />
</cc:interface>

<cc:implementation>
    .
    .
    .
    <f:ajax event="valueChange" execute="@this"
        listener="#{cc.attrs.ajaxEventListener}"
        render="#{cc.attrs.ajaxRenderTargets}" />
</cc:implementation>
如果可以去掉
AjaxBehaviorEvent
参数

public void genericAjaxEventLogger() {
    // ...
}
然后你可以用


如果参数是必需的(用于日志记录?),则需要按如下所示重新指定该属性


但是,这在这里并不像预期的那样适用于


在GF 3.1+Mojarra 2.1.1中:

SEVERE: javax.faces.FacesException: wrong number of arguments
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:89)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
    at com.sun.faces.facelets.el.ContextualCompositeMethodExpression.invoke(ContextualCompositeMethodExpression.java:177)
    at com.sun.faces.facelets.tag.TagAttributeImpl$AttributeLookupMethodExpression.invoke(TagAttributeImpl.java:450)
    at com.sun.faces.facelets.tag.jsf.core.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxHandler.java:447)
    at javax.faces.event.AjaxBehaviorEvent.processListener(AjaxBehaviorEvent.java:113)
    at javax.faces.component.behavior.BehaviorBase.broadcast(BehaviorBase.java:102)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:760)
    at javax.faces.component.UICommand.broadcast(UICommand.java:300)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    ... 28 more
我不确定这是否是一个错误。为此,我需要投入更多的时间来解决这个问题。但是,通过创建一个支持组件,从属性中获取
MethodExpression
,并使用正确数量的参数进行调用,这是一个可行的解决方案。下面是一个完整的启动示例:



无论如何,我相信,支持组件为实现您心中的功能需求的新方法打开了大门;)

您在什么环境下测试/使用它?我在GF 3.1和Tomcat 7以及Mojarra 2.1.1上都失败了。谢谢。我在CC接口中找到了很多声明action方法的示例,但没有一个用于声明listener方法。
listener()
方法签名的一部分
是JSF可以理解的特殊值吗?方法名称不相关。您甚至可以将其命名为
xyz()
。这只是一个自我描述的例子。最重要的是方法返回和参数类型的完整限定类名@巴卢斯你发现了相关的问题吗?Mojarra2.1.27+Tomcat6仍然存在这个问题(对于两个听众,一个有参数,另一个没有参数)。你认为值得为此开一个Jira问题吗?@BalusC我在使用这个结构时也遇到了一个例外。但是我尝试使用
,而不是ajax。它抱怨说“无法转换org.apache.el。MethodExpressionImpl@8819d678类型为org.apache.el.MethodExpressionImpl to interface javax.faces.event.ActionListener“感谢您的解决方案,它确实对我有帮助。是否可以通过传递带参数的方法来实现这一点?我的意思是,不要像示例中那样传递#{myBackingBean.updatedEventListenerXYZ},而是传递#{myBackingBean.myMethod(cc.attrs.myparam)}
package com.example;

import javax.el.MethodExpression;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;

@FacesComponent(value="testCC")
public class TestCC extends UINamingContainer {

    public void ajaxEventListener(AjaxBehaviorEvent event) {
        FacesContext context = FacesContext.getCurrentInstance();
        MethodExpression ajaxEventListener = (MethodExpression) getAttributes().get("ajaxEventListener");
        ajaxEventListener.invoke(context.getELContext(), new Object[] { event });
    }

}