gpt4 book ai didi

java - 在 Portlet 中安排任务

转载 作者:行者123 更新时间:2023-12-01 14:19:32 25 4
gpt4 key购买 nike

我有一个 portlet,在其中连接到数据库并显示一些数据。当启用自动刷新时,我想从数据库加载数据,然后每隔 X 秒刷新页面(jsp)。

但是,尽管我确实了解计时器和任务的工作原理,但我不太了解如何使它们在 portlet 中工作。

我尝试了两种不同的方法,但都没有达到我的预期。这是第一个使用 Thread.sleep(xxx); 函数

public void displayLog(final ActionRequest actionRequest,
final ActionResponse actionResponse) throws IOException,
PortletException {

do {
manager.setLastID(0);
redirectToLog(actionRequest, actionResponse);

try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while(manager.isAutoRefresh().equals("y"));
}

这是重定向函数:

public void redirectToLog(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {

// load messages and display them
manager.loadFromDB();

// in case of error, redirect to error page
if (manager.isConnError()) {
actionResponse.setRenderParameter("jspPage",
"/html/visual/error.jsp");
return;
}

// redirect
actionRequest.setAttribute("messages", manager.getMessages());
actionRequest.setAttribute("refresh", manager.isAutoRefresh());
actionRequest.setAttribute("serviceFilter", manager.getServiceFilter());
actionResponse
.setRenderParameter("jspPage", "/html/visual/display.jsp");

}

代码每 3 秒执行一次(如果我在那里放置一些打印语句,我可以看到它调用了这个函数)。但是,我没有被重定向到 jsp 页面。相反,它只是“卡住”并永远执行此 while 循环。

我还尝试了使用计时器的第二种方法:

class LogDbTask extends TimerTask {
private DbManager manager;
private PortletVisual portlet;
private ActionRequest actionRequest;
private ActionResponse actionResponse;

public LogDbTask(PortletVisual portlet, ActionRequest actionRequest, ActionResponse actionResponse) {
this.portlet = portlet;
this.actionRequest = actionRequest;
this.actionResponse = actionResponse;
manager = portlet.getManager();
}


public void run() {
if (manager.isAutoRefresh().equals("y")) {
try {
manager.setLastID(0);
portlet.redirectToLog(actionRequest, actionResponse);
} catch (IOException e) {
e.printStackTrace();
} catch (PortletException e) {
e.printStackTrace();
}
} else {
//Stop Timer.
this.cancel();
}
}
}

我称之为使用

Timer timer = new Timer("LogDbTimer");
LogDbTask task = new LogDbTask(this, actionRequest, actionResponse);
timer.schedule(task, 0, 3000);

但问题仍然是一样的 - 尽管这个函数被重复调用,但我从来没有进入过 jsp 页面。我不是 portelt 方面的专家,也不是多线程应用程序方面的专家。我究竟做错了什么?有什么简单的方法可以解决这个问题吗?

抱歉,这个问题让人筋疲力尽 - 我试图在其中放置一些代码示例。如果不理解,我会尝试更正确地指定问题......

最佳答案

Thread.sleep 方法一直“卡住”,因为 portlet 永远无法呈现 View 。它位于循环中,实际上从不返回页面来显示给用户。

计时器任务方法在设计上也存在缺陷。用户的浏览器必须向 portlet 代码发出页面请求,以将任何内容发送回用户。这本质上意味着 TimerTask 可能会执行,但当它执行时,响应已经发送给用户,并且您无法再更新页面。

我建议将计时器逻辑移至客户端。您可以编写一些 JavaScript 来使用 AJAX 和使用计时器的资源 URL 轮询 portlet。您的serveResource 方法可以只返回刷新的数据,然后更新JavaScript 中的 View 。这有助于防止全页刷新,从而减少服务器负载并使页面刷新更有效。

您唯一的其他选择是使用页面刷新 HTML 元标记或 JavaScript 计时器,让浏览器在您希望页面更新时执行整个页面刷新。这降低了避免使用 AJAX 的复杂性,但我认为这是一个性能较差且不太优雅的解决方案。

关于java - 在 Portlet 中安排任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17740755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com