我有一个Struts2 Action类,它在JMS队列中放置一个针对交易列表的JMS Fetch请求。此JMS Fetch消息由外部进程处理,可能需要几秒钟甚至几分钟的时间,具体取决于外部任务处理应用程序要处理的交易文件的数量。
我想知道如何用适当的响应来处理这个HTTP请求。客户是否等待交易列表返回(客户端(UI)必须对其进行操作,同时没有其他事情可做)
我接近它的方式是HTTP请求-->支柱2动作-->
- 调用Runnable以在单独的线程中运行(独立于Action类)
- UI等待
- 操作类线程在可运行之前一直处于睡眠状态
- 任务完成后,将交易列表返回到UI
流程如下:
- 将JMS获取请求放在队列1上
-
可运行的执行程序服务
CClass cclass = new CClass(); final ExecutorService execSvc = Executors.newFixedThreadPool(1); execSvc.execute(cclass);
当CClass实现可运行返回交易列表时:
List<Trade> tradesList = new ArrayList<Trade>();
@Override
public void run() {
while (true) {
try {
Message message = msgConsumer.receive(); // SYNCHRONOUS / NO MDB
if (message == null){
break;
}
if (message instanceof TextMessage) {
TextMessage txtMessage = (TextMessage) message;
Trade trade = TradeBuilder.buildTradeFromInputXML(txtMessage);
if (trade != null) {
tradesList.add(trade); // tradeList is a CClass class variable
}
}
} catch (JMSException e) {
logger.error("JMSException occurred ", e);
}
}
closeConnection();
}
当这个可运行程序正在执行时,我会在Action类中执行Thread.sleep(让可运行程序在单独的线程中执行)
// In Action class
try {
Thread.sleep(5000); // some time till when the runnable will get executed
} catch (InterruptedException e) {
e.printStackTrace();
}
execSvc.shutdown();
问题是,如果我在FutureTask中使用Callable并执行get(),那么在返回任何结果之前,它都将被阻塞。如果我做了一个Runnable,我必须让Action类Thread进入睡眠状态,直到Runnable执行完毕,tradeList可用。
使用Runnable方法,我能够将几百条记录返回到UI,在主Action类中提供5秒的Thread.sleep(),但当要获取数千条记录并在UI中显示时,只能部分构建tradeList。
这显然不是一种防失败的方法
有什么更好的建议吗?请在一个完整的请求-响应流程中说明处理步骤。
是的,在发出标准HTTP请求时有一种更好的方法(使用ajax可以做其他事情)。
您想看看Struts2执行和等待拦截器,它具有您已经实现的大部分功能。另请查看令牌拦截器。。。这可能很有用(它可以防止重复请求,但不像exec和wait那样提供愉快的等待屏幕)。