Java Wicket调用冗长的操作并通过ajax进行更新

Java Wicket调用冗长的操作并通过ajax进行更新,java,web-applications,web,osgi,wicket,Java,Web Applications,Web,Osgi,Wicket,基于此,我了解到Wicket会对后续AJAX请求进行排队。现在,我的页面上充斥着几个AJAX请求,我想再添加一个,这会产生一个冗长的操作 public void populateItem(final Item item) { final MyObject object = (MyObject) item.getModelObject(); // ... a couple of fields Label statusLabel = new Label("status", new Abs

基于此,我了解到Wicket会对后续AJAX请求进行排队。现在,我的页面上充斥着几个AJAX请求,我想再添加一个,这会产生一个冗长的操作

public void populateItem(final Item item) {
  final MyObject object = (MyObject) item.getModelObject();
  // ... a couple of fields
  Label statusLabel = new Label("status", new AbstractReadOnlyModel() {
    @Override
    public Object getObject() {
      return someService.doSomeLengthyOperation();
    }
  });
  statusLabel.add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(5)));
  item.add(statusLabel)
}
一旦这个Ajax请求触发,它可能需要一分钟来完成执行。这里的问题是
someService.doSomeLengthyOperation()
将执行
n倍于我拥有的行数
,这意味着我将在两分钟内排队
n次
。现在,正如我所提到的,Wicket对后续AJAX请求进行排队

发生的情况是,我需要
行数*分钟才能完成操作
加载页面或执行其他需要类似AJAX的操作

new AjaxButton("ajax-button"){
  @Override
  protected void onSubmit(AjaxRequestTarget target, Form form) {
    //.. this won't be executed until all the statusLabels have finished invoking getObject()
  }
}

我希望避免创建一个公开我的服务的web服务,并避免编写自己的AJAX调用。我有什么选择?(使用Wicket 1.5/Pax Wicket)

最简单的方法是让初始Ajax请求快速返回(没有任何结果),并向目标组件添加一个。如果有结果,该行为将检查间隔(比如每10秒左右一次)。如果有结果,它应该更新组件并删除自身

通过这种方式,您可以在单独的任务中执行该操作,而不会阻塞Ajax调用

为了详细说明一下,我创建了一个runnable,它发出5个Ajax调用,如您所描述的,每个调用运行10秒到1分钟之间的随机时间。同时,还有一个带有计数器的响应性AjaxLink

其主要思想是将实际的Ajax调用与对slow方法的调用分开

add(new ListView<DataHolder>("list", list) {

    @Override
    protected void populateItem(ListItem<DataHolder> item) {
        DataHolder dh = item.getModelObject();
        item.add(new Label("itemNumber", new PropertyModel<Integer>(dh, "number")));
        Label result = new Label("itemResult", new PropertyModel<String>(dh, "result"));
        result.setOutputMarkupId(true);
        result.add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(2)));
        item.add(result);
        Thread thread = new Thread(new Processor(item.getModelObject()));
        thread.start();
    }
});
processed成员只是一个标志,处理器使用它来指示何时完成等待(ehr工作)

由于您可能同时发布5个以上的线程,我建议使用某种线程池,但这超出了这个小演示的范围



免责声明:这不是生产代码。这只是为了演示。它不会善待你的资源,也不会优雅地处理任何资源的缺乏。当用户点击“重新加载”或发生任何其他情况时,它将无法工作。

我不完全确定WicketStuff异步任务是否可以帮助您,但请尝试一下:

以下是异步任务项目中的简短演示:

public class DemoPage extends WebPage implements IRunnableFactory {

public DemoPage() {

    Form<?> form = new Form<Void>("form");
    AbstractTaskContainer taskContainer = DefaultTaskManager.getInstance()
        .makeContainer(1000L, TimeUnit.MINUTES);
    ProgressButton progressButton = new ProgressButton("button", form, 
        Model.of(taskContainer), this, Duration.milliseconds(500L));
    ProgressBar progressBar = new ProgressBar("bar", progressButton);

    add(form);
    form.add(progressButton);
    form.add(progressBar);
}

@Override
public Runnable getRunnable() {
    return new IProgressObservableRunnable() {
        // Runnable implementation.
    };
}
公共类DemoPage扩展网页实现IRunnableFactory{
公共网页(){
表格=新表格(“表格”);
AbstractTaskContainer=DefaultTaskManager.getInstance()
.makeContainer(1000L,时间单位为分钟);
ProgressButton ProgressButton=新的ProgressButton(“按钮”,表单,
Model.of(taskContainer),这个,Duration.ms(500L));
ProgressBar ProgressBar=新的ProgressBar(“bar”,progressButton);
添加(表格);
表单添加(进度按钮);
添加表格(进度条);
}
@凌驾
public Runnable getRunnable(){
返回新的IProgressObservableRunTable(){
//可运行的实现。
};
}

你能更详细地解释一下你的问题吗?你有一个列表视图,其中的项是lenghtyOperation导致列表视图项非常缓慢地出现的。然后,当列表视图完成时,你得到了一个完整的ajax请求队列?你期望的行为是什么?啊,该死的,我这次解释得更好了吗?很抱歉造成混淆。Tak看一看,我仍然不完全理解。问题是,填充listview中的许多ajaxrequest实际上会阻止您使用按钮提交,因为该请求将是队列中的最后一个请求?是的,或多或少。考虑到我在
getObject()中执行的操作
方法可能需要几分钟的时间,它将阻止其他AJAX请求(例如
AjaxButton\onSubmit
),谢谢mate,但我实际上是在轮询某种状态,因此删除
ajaxSelfUpdatengTimerbehavior
是不可能的:(那么就不要删除它。这个解决方案根本不需要它。我的问题是,如果我不删除它,它将阻塞队列,如果我删除它,我将无法多次更新它。实际上,我正在寻找一个允许我异步运行Ajax调用的解决方案。我不认为,你理解我的想法。我将很快编辑我的答案,以包括在内。)一些演示代码。事实上,我是如何解决它的,为该方法公开了一个web服务,并编写了我自己的
Ajax
调用,但你的答案肯定是解决它的Wicket方法。感谢你的澄清,很抱歉回复太晚。
public class DemoPage extends WebPage implements IRunnableFactory {

public DemoPage() {

    Form<?> form = new Form<Void>("form");
    AbstractTaskContainer taskContainer = DefaultTaskManager.getInstance()
        .makeContainer(1000L, TimeUnit.MINUTES);
    ProgressButton progressButton = new ProgressButton("button", form, 
        Model.of(taskContainer), this, Duration.milliseconds(500L));
    ProgressBar progressBar = new ProgressBar("bar", progressButton);

    add(form);
    form.add(progressButton);
    form.add(progressBar);
}

@Override
public Runnable getRunnable() {
    return new IProgressObservableRunnable() {
        // Runnable implementation.
    };
}