Java Wicket 7-向导完成按钮生成多个onClick事件

Java Wicket 7-向导完成按钮生成多个onClick事件,java,wicket,Java,Wicket,我们正在使用Wicket向导组件。在向导的最后一步,我们发现如果用户快速单击finish按钮,Wicket会多次调用我们的onFinish()方法。这给我们带来了问题。 有趣的是,这个问题出现在我们尝试过的所有浏览器(即Chrome)中,但在Firefox中却没有。此浏览器似乎检测到多次单击,并且仅向服务器发送一次单击事件 问题是,我们能做些什么来防止这种情况? 通过查看Wicket框架代码,我可以看到导航按钮包含在向导按钮栏中,而完成按钮正在处理onClick事件,但我不确定覆盖或控制此行为的

我们正在使用Wicket
向导
组件。在向导的最后一步,我们发现如果用户快速单击finish按钮,Wicket会多次调用我们的
onFinish()
方法。这给我们带来了问题。 有趣的是,这个问题出现在我们尝试过的所有浏览器(即Chrome)中,但在Firefox中却没有。此浏览器似乎检测到多次单击,并且仅向服务器发送一次单击事件

问题是,我们能做些什么来防止这种情况?
通过查看Wicket框架代码,我可以看到导航按钮包含在
向导按钮栏中,而
完成按钮
正在处理
onClick
事件,但我不确定覆盖或控制此行为的正确方法,并以某种方式检测多个
onClick
事件

您似乎没有使用Ajax,是吗

如果您这样做了,您可以添加一个面纱-例如,通过覆盖
#getAjaxIndicatorMarkupId()
-可以防止任何双重提交。附加好处:如果用户在向导完成后按“上一步”按钮,浏览器将离开向导,用户无法再次完成向导

对于非Ajax请求,您必须向按钮添加自己的JavaScript。
要防止用户再次返回并完成向导,可以使用令牌基解决方案:
向导启动时,获取一个令牌(可能只是一个计数器)。向导完成后,将令牌标记为已使用(例如,将其存储在域对象中)。

每次请求向导时,您都可以检查令牌是否仍然有效-如果无效,请将用户重定向到另一个页面,说明向导已经完成。

您似乎不使用Ajax,是吗

如果您这样做了,您可以添加一个面纱-例如,通过覆盖
#getAjaxIndicatorMarkupId()
-可以防止任何双重提交。附加好处:如果用户在向导完成后按“上一步”按钮,浏览器将离开向导,用户无法再次完成向导

对于非Ajax请求,您必须向按钮添加自己的JavaScript。
要防止用户再次返回并完成向导,可以使用令牌基解决方案:
向导启动时,获取一个令牌(可能只是一个计数器)。向导完成后,将令牌标记为已使用(例如,将其存储在域对象中)。

每次请求向导时,您都可以检查令牌是否仍然有效-如果无效,请将用户重定向到另一个页面,说明向导已经完成。

Andrew非常友好地为我提交了原始问题。我确实尝试过这样做(基本上按照你的建议):

但是,我发现onFinish()的调用次数与我按下Finish按钮的次数相同,但是每次finishPressed进入方法时都是0,而不是计数递增

注意:我在日志中只看到过一次“init:finishPressed=0”。我不知道它怎么会一直重置为0。但是,我注意到每次onFinish()调用都由不同的线程处理。但是如上所述,构造函数(finishPressed的唯一位置设置为0)只调用了一次


只有将finishPressed声明为static(这显然会导致实际实时操作中出现问题),我才能看到finishPressed的增量与预期一致。

安德鲁非常友好地为我提交了原始问题。我确实尝试过这样做(基本上按照你的建议):

但是,我发现onFinish()的调用次数与我按下Finish按钮的次数相同,但是每次finishPressed进入方法时都是0,而不是计数递增

注意:我在日志中只看到过一次“init:finishPressed=0”。我不知道它怎么会一直重置为0。但是,我注意到每次onFinish()调用都由不同的线程处理。但是如上所述,构造函数(finishPressed的唯一位置设置为0)只调用了一次


只有将finishPressed声明为static(这显然会在实际实时操作中导致问题),我才能看到finishPressed按预期递增。

谢谢Sven。只需使用标准Wicket向导组件。如果你们能提供一个支持Ajax的向导,那就太好了;)它已经存在了:覆盖newButtonBar()并让它返回一个
AjaxWizardButtonBar
。谢谢Sven。只需使用标准Wicket向导组件。如果你们能提供一个支持Ajax的向导,那就太好了;)它已经存在了:重写newButtonBar()并让它返回一个
AjaxWizardButtonBar
class MyWizard extends Wizard {

    private Integer finishPressed = -1; // deliberately set an invalid value to start with

    public MyWizard() {
        finishPressed = 0;  // only place where finishedPressed is set to 0
        log.info( "init: finishPressed={}", finishPressed );
    }

    @Override
    public void onFinish() {
        log.info( "begin: finishPressed={}", finishPressed );
        if ( ! finishPressed ) {
            finishPressed += 1;
            // do onFinish actions ...
        }
        log.info( "end: finishPressed={}", finishPressed );
    }
}